---
title: Fundação da API em homologação
description: Conta, preferências, credenciais, capacidades, uso e diagnóstico disponíveis no marco A2.
---
:::caution[Homologação restrita]
Estas 17 operações estão implementadas em produção (`https://api.agilink.io/v1`) e homologação (`https://api.staging.agilink.io/v1`). O acesso exige conta autorizada no ambiente escolhido. A conta existente pode entrar no portal de produção; tokens antigos não são convertidos automaticamente em chaves novas. Os exemplos abaixo contêm identificadores e segredos fictícios.
:::

## Operações disponíveis

Os caminhos são relativos à base acima. **Humana** significa uma sessão autenticada do proprietário, validada pelo provedor e novamente no banco; API keys não administram conta nem outras chaves.

| Método e caminho | Permissão | Credencial | Entrada / resultado |
| --- | --- | --- | --- |
| `GET /me` | `identity:read` | Humana ou chave | Identidade mínima e revisão; chave não recebe nome/foto |
| `PATCH /me` | `profile:update` | Humana | `displayName`, `photoUrl`; perfil atualizado |
| `GET /me/preferences` | `preferences:read` | Humana | Aplicativo selecionado, tema e revisão |
| `PATCH /me/preferences` | `preferences:update` | Humana | `selectedAppId`, `theme`; preferências atualizadas |
| `GET /capabilities` | `capabilities:read` | Humana ou chave | Operações desta versão permitidas ao principal |
| `GET /apps/{appId}/capabilities` | `capabilities:read` | Humana ou chave | Mesmo catálogo, após verificar acesso ao aplicativo |
| `GET /apps/{appId}/usage` | `usage:read` | Humana ou chave | Contadores técnicos da credencial, conta e app |
| `GET /api-keys` | `api_keys:read` | Humana | Lista paginada de metadados |
| `POST /api-keys` | `api_keys:create` | Humana | Nome, apps, permissões e expiração; segredo uma vez |
| `GET /api-keys/{keyId}` | `api_keys:read` | Humana | Metadados e revisão |
| `PATCH /api-keys/{keyId}` | `api_keys:update` | Humana | Nome ou redução de apps/permissões/prazo |
| `POST /api-keys/{keyId}/rotate` | `api_keys:rotate` | Humana | `overlapSeconds`; nova chave e segredo uma vez |
| `DELETE /api-keys/{keyId}` | `api_keys:delete` | Humana | Revogação; 204 sem corpo |
| `GET /audit-events` | `audit_events:read` | Humana | Lista paginada das alterações da conta |
| `GET /requests` | `requests:read` | Humana | Lista paginada de diagnóstico sanitizado da conta |
| `GET /operations/{operationId}` | `operations:read` | Humana ou chave | Estado/revisão de operação visível |
| `POST /operations/{operationId}/cancel` | `operations:cancel` | Humana ou chave | Intenção de cancelamento; 202 e estado atual |

A [referência OpenAPI](/referencia/) apresenta parâmetros, schemas e exemplos de request/response de cada operação. A propriedade `x-agilink-state` distingue `available_staging` de `design_only`; as 143 operações administrativas atuais estão disponíveis em homologação. OAuth e MCP permanecem desabilitados.

## Autenticação

Envie `Authorization: Bearer <credencial>`. Sessões humanas são emitidas pelo Supabase Auth do projeto de homologação, usando o fluxo de login do produto; a Platform API não recebe senha nem cria um endpoint de login paralelo. Nunca use uma chave administrativa do provedor para integrar um usuário.

Chaves de servidor usam o prefixo `agl_test_` em homologação. O segredo aleatório é exibido uma vez e somente o digest fica no banco. Permissões são conferidas por operação; o acesso ao recurso ainda exige que pertença ao proprietário e a um app autorizado. Identificadores de outra conta/app retornam 404. Credencial inválida, revogada, expirada ou de proprietário inativo retorna 401; falta de permissão retorna 403.

## Ler e editar perfil

```http
GET /v1/me HTTP/1.1
Host: api.staging.agilink.io
Authorization: Bearer <sessao-humana>
```

```http
HTTP/1.1 200 OK
ETag: "c0000000-0000-4000-8000-000000000001"
Cache-Control: no-store, no-transform
Content-Type: application/json; charset=utf-8
```

```json
{
  "data": {
    "userId": "a0000000-0000-4000-8000-000000000001",
    "displayName": "Ana",
    "photoUrl": null,
    "actorType": "human",
    "revision": "c0000000-0000-4000-8000-000000000001"
  },
  "meta": {"requestId": "req_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
}
```

Use o ETag completo, incluindo aspas, ao editar:

```http
PATCH /v1/me HTTP/1.1
Host: api.staging.agilink.io
Authorization: Bearer <sessao-humana>
Content-Type: application/json
If-Match: "c0000000-0000-4000-8000-000000000001"
Idempotency-Key: d0000000-0000-4000-8000-000000000001

{"displayName":"Ana Silva"}
```

O resultado tem o mesmo schema de `GET /me`, com nome atualizado e uma nova `revision`/ETag. Campos omitidos são preservados. `photoUrl:null` remove a foto. Campos desconhecidos são rejeitados; e-mail, senha e privilégios não fazem parte deste PATCH. `PATCH /me/preferences` segue o mesmo padrão; `{"selectedAppId":null,"theme":"system"}` limpa a seleção e usa o tema do sistema.

Sem `If-Match`, a API retorna 428; revisão antiga retorna 412. Uma nova edição exige consultar a revisão atual e usar uma nova intenção de idempotência.

## Emitir, reduzir, rotacionar e revogar uma chave

```http
POST /v1/api-keys HTTP/1.1
Host: api.staging.agilink.io
Authorization: Bearer <sessao-humana>
Content-Type: application/json
Idempotency-Key: d0000000-0000-4000-8000-000000000002

{"name":"Meu backend","appIds":["app_loja"],"permissions":["identity:read","capabilities:read","usage:read"]}
```

```json
{
  "data": {
    "key": {
      "id": "b0000000-0000-4000-8000-000000000001",
      "name": "Meu backend",
      "prefix": "agl_test_aaaaaa",
      "appIds": ["app_loja"],
      "permissions": ["identity:read","capabilities:read","usage:read"],
      "expiresAt": "2027-01-17T22:00:00.000Z",
      "createdAt": "2026-10-19T22:00:00.000Z",
      "lastUsedAt": null,
      "revokedAt": null,
      "revision": "c0000000-0000-4000-8000-000000000002"
    },
    "secret": "agl_test_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  },
  "meta": {"requestId":"req_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}
}
```

A resposta é 201 com `Location: /v1/api-keys/{keyId}`. Guarde o segredo em um gerenciador de segredos. O prazo padrão é 90 dias e o máximo permitido é 365 dias, sem renovação automática. Listagens e consultas nunca incluem `secret`.

`PATCH /api-keys/{keyId}` permite renomear e reduzir o alcance. Por exemplo, `{"permissions":["identity:read"]}` retira as demais permissões. Ampliar o alcance exige emissão de outra chave. O prazo não pode ser estendido por PATCH.

`POST /api-keys/{keyId}/rotate`, com `{"overlapSeconds":0}`, emite outra chave e revoga imediatamente a anterior. Sobreposição opcional vai de 0 a 86400 segundos e não estende uma expiração anterior mais próxima. A nova chave preserva o prazo e o alcance restantes. Envie `If-Match` e `Idempotency-Key` nessas ações.

`DELETE /api-keys/{keyId}`, também com revisão e intenção, revoga a chave e retorna 204. Repetir a mesma intenção confirmada retorna 204. A próxima requisição feita com o segredo revogado retorna 401.

## Repetição e perda de resposta

Toda mutação exige `Idempotency-Key` UUID v4. Durante 24 horas, repetir método/caminho/conteúdo/revisão com a mesma chave e credencial recupera o resultado confirmado, após verificar a autorização atual. A resposta informa `Idempotency-Replayed:true` e recebe um novo `requestId`. O efeito e a quota de escrita não são repetidos; a proteção de entrada continua valendo.

Alterar o conteúdo com a mesma chave retorna 409 `idempotency_conflict`. Uma intenção concorrente pode receber 409 `operation_in_progress` e `Retry-After`. Após expirar o recibo, a mesma chave poderá ser admitida como uma nova intenção; não dependa dela como deduplicação permanente.

Emissão/rotação são exceções à reexibição: se o segredo já foi emitido e a resposta se perdeu, o retry retorna 409 `secret_not_replayable`, com `error.resource.id` e `Location`. Consulte e revogue a chave identificada antes de emitir outra. O recibo não contém o segredo.

## Paginação e diagnóstico

`GET /api-keys`, `/audit-events` e `/requests` aceitam `limit` de 1 a 100 (padrão 50) e `cursor`. A ordem é data decrescente e ID como desempate. Continue com `pagination.nextCursor`, mantendo credencial e limite. Cursor expirado (15 minutos), alterado ou de outro contexto retorna 400. As listas são mutáveis e não fornecem um snapshot.

Auditoria registra operação, ator, recurso, revisão e identificador de correlação. Requisições registram operação, status, duração e código de erro. Retenção inicial: 90 dias para auditoria e 30 dias para diagnóstico. Não são registrados corpos, senhas, segredos ou cabeçalhos de autenticação.

## Limites técnicos

As janelas são fixas de 60 segundos, em UTC, com contadores SQL consistentes:

| Categoria | Por credencial | Por conta, somando credenciais | Por app, somando credenciais |
| --- | --- | --- | --- |
| Entrada autenticada | 1200 | 2400 | 1200 |
| Leitura | 600 | 1200 | 600 |
| Escrita admitida | 120 | 240 | 120 |

Uma chamada participa do limite de app quando sua rota identifica o app. Os adaptadores dos próximos recursos também devem fornecer o app resolvido ao controle comum. Há ainda proteção aproximada por IP na borda; ela não substitui os contadores SQL.

Consulte `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (Unix em segundos) e `X-RateLimit-Policy`. O header informa a dimensão mais próxima de esgotar; uma negativa retorna 429 e `Retry-After`. Aumentar o número de chaves não aumenta o orçamento compartilhado da conta/app.

`GET /apps/{appId}/usage` retorna `limits`/`usage` da credencial e `sharedLimits`/`sharedUsage` da conta e do app. O contador da conta inclui os demais apps do proprietário; nenhuma informação de outra conta é retornada. Estes limites são proteções técnicas da homologação; não representam franquias comerciais, cobrança ou medição de carga.

Corpos JSON são limitados a 32 KiB, inclusive quando enviados em partes. Campos não previstos, tipos incorretos e revisões fracas (`W/`) são rejeitados. CORS é restrito às origens configuradas, e respostas privadas não permitem armazenamento ou transformação intermediária.

## Operações duráveis

Consulta e cancelamento estão disponíveis; domínios, lotes, importações e exportações já criam jobs de produto nesta versão. O tipo interno de verificação `foundation.noop` não possui endpoint público de criação.

Estados previstos: `queued`, `running`, `succeeded`, `partially_succeeded`, `failed`, `cancel_requested`, `cancelled`. O processamento usa lease de 30 segundos, renovação e autorização atual em cada retomada/conclusão. Uma execução antiga não conclui uma lease nova. Até cinco tentativas são permitidas após interrupção; o intervalo mínimo entre retomadas cresce progressivamente. Falhas definitivas terminam em `failed`, com erro sanitizado.

O cancelamento retorna 202 e o estado atual, com `Location`/`Retry-After`. Ele impede trabalho pendente quando observado pelo consumidor; não desfaz efeitos já confirmados. Nenhum percentual de progresso é estimado para efeitos externos.
