# Autenticação

Todas as chamadas que executam um modelo ou leem os seus pedidos precisam de uma chave de API. O catálogo (`GET /models`,
`GET /categories`), `POST /quote` e o documento OpenAPI são públicos.

## Chaves de API

Crie e revogue chaves em [https://doitong.com/developers/dashboard#keys](https://doitong.com/developers/dashboard#keys). Uma chave tem o formato
`doitong_` seguido de 64 caracteres hexadecimais e é apresentada apenas uma vez, quando a cria. Envie-a no cabeçalho
`Authorization`:

```bash
curl https://api.doitong.com/v1/account -H "Authorization: Bearer $DOITONG_API_KEY"
```

`X-API-Key: <key>` também funciona.

> [!WARNING]
> Mantenha as chaves no seu servidor: qualquer pessoa que tenha uma chave pode gastar os créditos de API que esta está
> autorizada a gastar. Se uma chave for divulgada, revogue-a e crie uma nova.

Um pedido sem chave recebe `401` com o código `missing_api_key`; uma chave desconhecida, revogada ou expirada também recebe `401`.

## Âmbitos

Cada chave tem âmbitos. A API de modelos verifica estes:

| Ação | Âmbito necessário |
|---|---|
| Executar um modelo, cancelar um pedido, eliminar os ficheiros de um pedido, alterar a definição de armazenamento | `models:run` (as chaves com os antigos `images:create` ou `videos:create` também funcionam) |
| Criar um URL de carregamento | `models:run` ou `media:upload` |
| Ler pedidos e a conta | `models:read` (uma chave que possa executar modelos também pode ler) |

As novas chaves recebem `models:read` e `models:run` por predefinição. Uma chamada sem o âmbito correto recebe `403` com o
código `insufficient_scope`.

## Orçamentos de créditos

Uma chave pode ter o seu próprio orçamento em créditos de API (1000 créditos da API = 1 $), definido pelo titular da conta: um
orçamento total, um orçamento diário (últimas 24 horas) ou ambos. Antes de cobrar uma execução, o custo é comparado com o
que a chave já gastou através desta API (líquido de reembolsos). Uma execução que o excedesse é recusada com `402
budget_exceeded` e não é cobrado qualquer valor.

> [!IMPORTANT]
> Uma recusa por orçamento é definitiva: repetir não ajudará até o titular aumentar o orçamento.

 Uma chave sem orçamento pode
gastar até ao saldo de API. Separadamente, uma execução que o saldo de API não consiga cobrir recebe `402
insufficient_credits` com um `top_up_url`.

`GET https://api.doitong.com/v1/account` apresenta o saldo de API e o orçamento restante da chave (ambos em créditos de API):

```json 200 OK · conta
{
  "object": "account",
  "credits": 125000,
  "balance": { "credits": 125000, "usd": "125.00" },
  "top_up_url": "https://doitong.com/developers/dashboard#balance",
  "key": {
    "name": "Production server",
    "prefix": "doitong_3fa9c1e...",
    "scopes": ["models:read", "models:run"],
    "budget_remaining": 50000,
    "rate_limit": 3600,
    "rate_limit_remaining": 3571
  },
  "webhook_signing_secret": "whsec_..."
}
```

`budget_remaining` é `null` quando a chave não tem orçamento próprio.

## Limites de frequência

Cada chave pode fazer 3600 pedidos por hora, salvo se o seu limite tiver sido definido de forma diferente. Todas as
respostas autenticadas incluem o estado atual:

| Cabeçalho | Significado |
|---|---|
| `X-RateLimit-Limit` | Pedidos permitidos na janela atual |
| `X-RateLimit-Remaining` | Pedidos restantes na janela atual |
| `X-RateLimit-Reset` | Hora Unix em que a janela é reposta |

Quando ultrapassa o limite, recebe `429` com um cabeçalho `Retry-After` (segundos). A consulta prolongada com `?wait=`
conta como um pedido por chamada, pelo que esperar é mais económico do que consultar rapidamente.

Existe também um limite de 10 pedidos em curso (`queued` ou `running`) por conta. Iniciar mais um devolve
`429 too_many_inflight`; inicie-o novamente depois de um terminar.
