> ## 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.

# Platform API — visão geral

> Entitlements, status de assinante, billing e webhooks — a base compartilhada por todo parceiro Googa.

A Platform API é a camada comum que todo parceiro integra **uma vez**, independente de quais
produtos (NovelAI, HistorinhAI, NovelAudio) ele vai ativar. Ela resolve quatro problemas:

<CardGroup cols={2}>
  <Card title="Quem pode acessar o quê" icon="key">
    **Entitlements** — ativa, suspende ou cancela o acesso de um assinante a um produto, no
    momento em que o status dele muda no sistema do parceiro (nova assinatura, upgrade, suspensão
    por inadimplência).
  </Card>

  <Card title="O que está ativo agora" icon="list-check">
    **Subscriber Status** — consulta pontual do que um assinante tem direito a acessar em um
    produto, independente de quando o entitlement foi emitido.
  </Card>

  <Card title="Quanto cobrar" icon="receipt">
    **Billing Usage** — a contagem de exemplares ativos, base para a reconciliação da Nota de
    Débito mensal.
  </Card>

  <Card title="Quem é o leitor" icon="fingerprint">
    **SSO / OIDC** — *planejado, ainda não implementado*: login federado, em que o assinante
    entra pelo app do parceiro (ex: Minha Algar) e cai autenticado no produto Googa, sem criar
    senha nova.
  </Card>
</CardGroup>

## Autenticação

Toda chamada de servidor-a-servidor (Entitlements, Subscriber Status, Billing Usage) usa OAuth2
**client credentials** — seu backend troca `client_id`/`client_secret` por um token de curta
duração (10 minutos) em `POST /oauth2/token`, e usa esse token nas chamadas seguintes. As
credenciais são aceitas via **HTTP Basic** (`Authorization: Basic base64(client_id:client_secret)`,
RFC 6749 §2.3.1 — a forma preferida) ou nos campos do corpo `application/x-www-form-urlencoded`.
Cada endpoint exige um escopo específico (`entitlements:write`, `subscriber:read`,
`billing:read`); os escopos do token são os cadastrados na credencial do parceiro. Ver [Modelo de
autenticação sobre Supabase](/architecture/supabase-auth-model) para o desenho interno completo.

O SSO do assinante (`GET /oauth2/authorize`) é um fluxo diferente — de navegador, não de API — e
está **planejado, ainda não implementado**: não existe hoje endpoint de SSO em nenhum ambiente.

## Domínio

```
https://api.googa.com.br/v1
```

Este é o único domínio da Platform API — ele é o mesmo independente de quais produtos o parceiro
ativa. As APIs específicas de cada produto (catálogo, progresso de leitura, streaming de áudio)
vivem em domínios próprios: `api.novelai.com.br` (NovelAI **e** NovelAudio,
que compartilham o mesmo backend) e `api.historinhai.com.br`. Ver as abas correspondentes.

## Eventos (webhooks de saída)

| Evento                  | Quando dispara                                                    |
| ----------------------- | ----------------------------------------------------------------- |
| `subscriber.updated`    | Entitlement de um assinante é criado ou atualizado (status/plano) |
| `subscription.canceled` | Status do entitlement transiciona para `canceled`                 |

O mecanismo real: um Database Webhook nativo do Supabase (trigger `pg_net`) dispara, na mudança
de linha, uma chamada à função de despacho (`webhook-dispatch`, projeto Platform), que **assina o
payload com HMAC-SHA256** e entrega ao `webhook_url` cadastrado do parceiro. A entrega ao
parceiro é feita em **uma única tentativa por disparo** — o retry nativo do Database Webhook
cobre falha ao invocar a função de despacho, mas não existe fila própria de reentrega ao endpoint
do parceiro. Responda 2xx rápido.

**Verificando a assinatura** (o essencial):

1. Leia o **corpo bruto** da requisição (bytes, antes de qualquer parse de JSON).
2. Calcule HMAC-SHA256 do corpo usando o `webhook_secret` combinado no cadastro do parceiro.
3. Compare o resultado (hex), em tempo constante, com o header `X-Googa-Signature`
   (formato `sha256=<hmac-hex>`).
4. O header `X-Googa-Event` traz o nome do evento (`subscriber.updated` /
   `subscription.canceled`) sem precisar parsear o corpo.

O payload tem o formato `{ "event": "...", "occurred_at": "...", "data": { "subscriber_id",
"product", "status" } }` — ver os schemas na Referência de API.
