> ## Documentation Index
> Fetch the complete documentation index at: https://developers.googa.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Emite uma URL de reprodução assinada para um capítulo liberado

> Verifica entitlement (plano do assinante inclui áudio + capítulo já liberado pela cadência de 1 capítulo/dia — mesma regra de drip do NovelAI, com acesso antecipado no plano VIP) antes de emitir a URL. Nunca devolve o áudio bruto no corpo da resposta — apenas a URL assinada de curta duração para o player buscar a mídia.
Honestidade sobre `format`/adaptação de bitrate: a proposta técnica original promete streaming adaptativo HLS/DASH. O pipeline real hoje (Edge Function `audio-url` sobre o bucket privado `chapter-audio`) assina a URL de um único arquivo mp3/aac de bitrate fixo, com TTL de **1200 segundos (20 minutos)** — o valor no código; foi elevado de 2 minutos porque o player busca a mídia por range requests durante a reprodução e a URL curta expirava no meio de capítulos longos. O valor final ainda depende de uma decisão humana de trade-off segurança × confiabilidade antes do deploy. A URL continua curta demais para virar link de compartilhamento útil, mas isto **não** é streaming adaptativo. Empacotamento HLS/DASH real (segmentação, manifesto, múltiplos bitrates) é trabalho de roadmap ainda não iniciado; até lá, `format` sempre retorna `mp3`.



## OpenAPI

````yaml /novelaudio/openapi.yaml get /novels/{id}/chapters/{chapterNumber}/stream
openapi: 3.1.0
info:
  title: Googa NovelAudio API
  version: 1.0.0
  summary: >-
    Catálogo em áudio, streaming de capítulo e posição de reprodução do
    NovelAudio. Vive no MESMO domínio e no MESMO backend físico do NovelAI —
    NovelAI e NovelAudio compartilham um único projeto Supabase ("Novel"), e
    esta API só existe como uma superfície de recursos diferente (áudio, não
    texto) dentro dele. Não existe `api.novelaudio.com.br`.
  description: >-
    Hoje o único cliente do NovelAudio é o próprio app oficial, falando
    diretamente com o Supabase do projeto "Novel" (PostgREST + Edge Functions +
    Storage). Esta especificação é o contrato para um parceiro (ex: uma
    operadora) embutir o player de áudio no próprio app ou puxar métricas de
    escuta sem acesso direto ao banco.

    Por que o domínio é `api.novelai.com.br` e não um domínio próprio: ver
    [Visão geral do NovelAudio](/novelaudio/overview) e [Modelo de autenticação
    sobre Supabase](/architecture/supabase-auth-model). Em resumo — NovelAI e
    NovelAudio são dois apps sobre o mesmo projeto Supabase; a Edge Function
    resolve por rota/recurso (texto vs. áudio), não por domínio, então um
    `api.novelaudio.com.br` separado bateria na mesma infraestrutura sem
    necessidade.

    Honestidade sobre o gap entre o prometido e o real (importante para quem for
    implementar contra este contrato): a proposta técnica original (RFP Livros
    Digitais 2026) promete narração neural com múltiplas vozes selecionáveis e
    streaming adaptativo HLS/DASH. O que existe hoje é bem mais modesto — ver a
    descrição de cada endpoint abaixo, e a seção "Como o áudio é produzido hoje"
    em [/novelaudio/overview](/novelaudio/overview).

    Esta especificação é um **contrato proposto, ainda não implementado** —
    nenhum destes endpoints existe em produção.

    Autenticação: o token de parceiro é emitido **uma única vez, pela Platform
    API** (`POST https://api.googa.com.br/v1/oauth2/token` — ver [Platform —
    OAuth2](/platform/reference/oauth2/troca-client-credentials-por-um-token-de-acesso-de-parceiro));
    nem o NovelAudio nem o NovelAI têm endpoint de token próprio. Este arquivo
    não repete essa operação; ele só declara os escopos `novelaudio:*` que
    também podem ser solicitados nessa mesma troca, ao lado dos escopos
    `novelai:*`. Um parceiro que integra catálogo de texto e áudio no mesmo
    cliente pede os dois conjuntos de escopo numa única chamada ao endpoint de
    token da Platform.
  contact:
    name: Googa — Suporte a parceiros
    email: developers@googa.com.br
  license:
    name: Uso restrito — ver Política de Uso da API
    url: https://developers.googa.com.br/security/api-usage-policy
servers:
  - url: https://api.novelai.com.br/v1
    description: >-
      Produção (proposto). Mesmo domínio e mesmo backend físico do NovelAI — NÃO
      é um domínio separado do NovelAudio. Roteamento por recurso, não por host.
  - url: https://sandbox.novelai.com.br/v1
    description: Sandbox (proposto) — dados fictícios, sem impacto em billing real.
security:
  - partnerOAuth2: []
tags:
  - name: Audio Metadata
    description: >-
      Metadados de áudio por novela e por capítulo — vozes, duração, status de
      renderização.
  - name: Streaming
    description: >-
      Emissão de URL de reprodução de um capítulo específico, com verificação de
      entitlement.
  - name: Playback
    description: Posição de reprodução do assinante, para retomar entre dispositivos.
  - name: Voices
    description: >-
      Catálogo de vozes de narração disponíveis. Hoje inteiramente Roadmap — ver
      descrição do endpoint.
paths:
  /novels/{id}/chapters/{chapterNumber}/stream:
    get:
      tags:
        - Streaming
      summary: Emite uma URL de reprodução assinada para um capítulo liberado
      description: >-
        Verifica entitlement (plano do assinante inclui áudio + capítulo já
        liberado pela cadência de 1 capítulo/dia — mesma regra de drip do
        NovelAI, com acesso antecipado no plano VIP) antes de emitir a URL.
        Nunca devolve o áudio bruto no corpo da resposta — apenas a URL assinada
        de curta duração para o player buscar a mídia.

        Honestidade sobre `format`/adaptação de bitrate: a proposta técnica
        original promete streaming adaptativo HLS/DASH. O pipeline real hoje
        (Edge Function `audio-url` sobre o bucket privado `chapter-audio`)
        assina a URL de um único arquivo mp3/aac de bitrate fixo, com TTL de
        **1200 segundos (20 minutos)** — o valor no código; foi elevado de 2
        minutos porque o player busca a mídia por range requests durante a
        reprodução e a URL curta expirava no meio de capítulos longos. O valor
        final ainda depende de uma decisão humana de trade-off segurança ×
        confiabilidade antes do deploy. A URL continua curta demais para virar
        link de compartilhamento útil, mas isto **não** é streaming adaptativo.
        Empacotamento HLS/DASH real (segmentação, manifesto, múltiplos bitrates)
        é trabalho de roadmap ainda não iniciado; até lá, `format` sempre
        retorna `mp3`.
      operationId: getChapterStreamUrl
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Identificador da novela no catálogo Googa.
        - name: chapterNumber
          in: path
          required: true
          schema:
            type: integer
            minimum: 1
          description: >-
            Número do capítulo (1-indexado). Precisa estar liberado para o
            assinante pela cadência de drip.
        - name: subscriber_id
          in: query
          required: true
          schema:
            type: string
          description: >-
            Identificador do assinante no sistema do parceiro — usado para
            resolver o entitlement e registrar o acesso em log de auditoria.
      responses:
        '200':
          description: URL de reprodução emitida.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StreamResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            Plano sem áudio, ou capítulo ainda não liberado pela cadência de
            drip para este assinante.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            Áudio deste capítulo ainda não foi renderizado (`audio_status`
            diferente de `ready`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    StreamResponse:
      type: object
      properties:
        stream_url:
          type: string
          format: uri
          description: >-
            URL assinada de curta duração — 1200 segundos (20 minutos) no código
            hoje; o valor final ainda depende de decisão humana antes do deploy.
            Nunca cachear ou reutilizar após expirar.
        expires_in:
          type: integer
          example: 1200
          description: Segundos até a URL expirar.
        format:
          type: string
          enum:
            - mp3
            - hls
            - dash
          description: >-
            Hoje sempre `mp3` (arquivo único, bitrate fixo). `hls`/`dash` são o
            alvo de roadmap para streaming adaptativo — ver descrição do
            endpoint.
        duration_seconds:
          type: integer
          nullable: true
    Error:
      type: object
      description: >-
        Mesmo formato de erro (estilo OAuth2, RFC 6749 §5.2) usado pela Platform
        API.
      properties:
        error:
          type: string
          example: invalid_request
        error_description:
          type: string
          example: Capítulo ainda não liberado pela cadência de drip
  responses:
    Unauthorized:
      description: Credenciais ausentes, inválidas ou expiradas.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    partnerOAuth2:
      type: oauth2
      description: >-
        Client credentials — emitido **uma única vez**, de forma centralizada,
        pela Platform API (`POST https://api.googa.com.br/v1/oauth2/token`, ver
        [Platform —
        OAuth2](/platform/reference/oauth2/troca-client-credentials-por-um-token-de-acesso-de-parceiro)).
        Este domínio (`api.novelai.com.br`, que também atende NovelAudio) só
        valida o token — via a chave pública do projeto Platform — nunca emite
        um token próprio. Este arquivo não redefine a operação de emissão, só
        declara os escopos `novelaudio:*` que também podem ser pedidos na mesma
        troca, ao lado dos `novelai:*`.
      flows:
        clientCredentials:
          tokenUrl: https://api.googa.com.br/v1/oauth2/token
          scopes:
            novelaudio:audio:read: Consultar metadados de áudio e emitir URLs de streaming
            novelaudio:playback:read: Consultar posição de reprodução
            novelaudio:playback:write: Atualizar posição de reprodução
            novelaudio:voices:read: >-
              Consultar o catálogo de vozes de narração (roadmap — ver `GET
              /voices`)

````