API Keys
Endpoints administrativos da WebApiAlcance para gerenciar API Keys - as credenciais que autenticam o acesso à própria API. Cobrem geração de novas chaves, listagem geral (restrita a perfil administrador/diretoria), listagem das chaves do usuário logado, detalhamento por ID, atualização, exclusão e o gerenciamento dos escopos associados a cada chave.
Domínio administrativo - nunca exponha ao MCP
Este é um domínio de gestão de credenciais. Ele governa a emissão e a revogação das próprias chaves de acesso à API e NUNCA deve ser exposto ao gateway MCP nem a clientes de IA. Expor estes endpoints permitiria a um cliente autônomo criar chaves, escalar os próprios escopos e apagar credenciais - uma falha de segurança grave. Mantenha api_keys:read e api_keys:write fora de qualquer API Key emitida para o MCP.
Todos os endpoints exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs.
Base path
/api/v1/api-keysA URL completa em produção é https://api.contabilidadealcance.com.br/api/v1/api-keys.
Escopos necessários
api_keys:read- listagem, detalhamento e leitura de escoposapi_keys:write- geração, atualização, exclusão e substituição de escopos
O escopo é derivado da rota, mas com uma pegadinha de normalização: o prefixo da URL é /api-keys (com hífen), porém o recurso de escopo é api_keys (com underscore) - o hífen do path vira underscore no código do escopo. A ação segue o método HTTP: read para GET e write para POST/PUT/PATCH/DELETE. Portanto os escopos corretos são api_keys:read e api_keys:write, não api-keys:read.
Controles de privilégio
Além dos escopos, alguns endpoints aplicam regras extras: GET /api-keys/ exige perfil administrador ou diretoria (require_perfil); apenas esses dois perfis podem conceder escopo_global; e um usuário funcionario não pode criar/atribuir a uma chave escopos além dos seus próprios (princípio do menor privilégio). O acesso a uma chave específica também exige propriedade (require_api_key_ownership): administrador/diretoria acessam qualquer chave, funcionario só as próprias (a chave inexistente ainda responde 404, avaliado antes da checagem de perfil).
Endpoints
POST /api-keys/
Gera uma nova API Key para o usuário logado. Retorna a chave criada com o segredo em texto puro no campo api_key - exibido uma única vez. escopo_global = true só é aceito de perfil administrador/diretoria (403 caso contrário) e um usuário funcionario só pode informar scope_ids que já possua (escopos além dos seus geram 403).
Parâmetros
Este endpoint não recebe parâmetros de rota ou query - os dados vão no corpo da requisição (ApiKeyCreate): nome (obrigatório), expiracao (default "nunca"), escopo_global (default false) e scope_ids (default []).
Request
{
"nome": "Integração DCTFWeb",
"expiracao": "nunca",
"escopo_global": false,
"scope_ids": [3, 8]
}Response 200 OK
{
"success": true,
"message": "API Key gerada com sucesso! Guarde a chave, ela nao sera exibida novamente.",
"data": {
"id": 42,
"usuario_id": 7,
"nome": "Integração DCTFWeb",
"key_prefix": "ak_live_9f3b",
"expiracao": "nunca",
"data_expiracao": null,
"ativo": true,
"escopo_global": false,
"criado_em": "2026-07-03T09:15:00-03:00",
"ultimo_uso": null,
"scopes": [],
"api_key": "ak_live_9f3b8c1d2e4f5a6b7c8d9e0f1a2b3c4d"
}
}O segredo aparece só uma vez
O campo api_key (o segredo em texto puro) é retornado exclusivamente nesta resposta de criação. Ele não é armazenado de forma recuperável e nunca volta a ser exibido - nem no GET /me, nem no GET /{api_key_id}, que só devolvem o key_prefix. Copie e guarde o valor com segurança no momento da criação; se perder, a única saída é revogar a chave e gerar outra.
Escopo: api_keys:write
GET /api-keys/
Lista todas as API Keys de todos os usuários. Endpoint restrito a perfil administrador ou diretoria (require_perfil); um usuário funcionario recebe 403. O segredo em texto puro nunca é incluído.
Parâmetros
Este endpoint não recebe parâmetros de rota ou query. A resposta traz um array de ApiKeyRead.
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "API Keys listadas com sucesso!",
"data": [
{
"id": 42,
"usuario_id": 7,
"nome": "Integração DCTFWeb",
"key_prefix": "ak_live_9f3b",
"expiracao": "nunca",
"data_expiracao": null,
"ativo": true,
"escopo_global": false,
"criado_em": "2026-07-03T09:15:00-03:00",
"ultimo_uso": null,
"scopes": []
}
]
}Escopo: api_keys:read (além de perfil administrador ou diretoria)
GET /api-keys/me
Lista as API Keys do usuário logado. Lista vazia é um estado válido - retorna 200 OK com data: [].
Parâmetros
Este endpoint não recebe parâmetros de rota ou query. A resposta traz um array de ApiKeyRead.
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Suas API Keys listadas com sucesso!",
"data": [
{
"id": 42,
"usuario_id": 7,
"nome": "Integração DCTFWeb",
"key_prefix": "ak_live_9f3b",
"expiracao": "nunca",
"data_expiracao": null,
"ativo": true,
"escopo_global": false,
"criado_em": "2026-07-03T09:15:00-03:00",
"ultimo_uso": "2026-07-05T14:22:00-03:00",
"scopes": []
}
]
}Escopo: api_keys:read
GET /api-keys/{api_key_id}
Detalha uma API Key pelo ID inteiro. Exige que a chave pertença ao usuário logado, salvo perfil administrador/diretoria, que acessa qualquer chave (require_api_key_ownership). Quando não encontrada, retorna 404 Not Found - avaliado antes da checagem de perfil.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
api_key_id | int | path | sim | ID interno da chave |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "API Key encontrada!",
"data": {
"id": 42,
"usuario_id": 7,
"nome": "Integração DCTFWeb",
"key_prefix": "ak_live_9f3b",
"expiracao": "nunca",
"data_expiracao": null,
"ativo": true,
"escopo_global": false,
"criado_em": "2026-07-03T09:15:00-03:00",
"ultimo_uso": "2026-07-05T14:22:00-03:00",
"scopes": []
}
}Escopo: api_keys:read
PUT /api-keys/{api_key_id}
Atualiza uma API Key existente. O body é um ApiKeyUpdate com campos parciais (exclude_unset) - somente o que vier preenchido é alterado. Permite renomear (nome) e ativar/desativar (ativo) a chave. Exige propriedade da chave (require_api_key_ownership), salvo perfil administrador/diretoria.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
api_key_id | int | path | sim | ID da chave |
Request (ApiKeyUpdate - todos os campos opcionais)
{
"nome": "Integração DCTFWeb (produção)",
"ativo": false
}Response 200 OK
{
"success": true,
"message": "API Key atualizada com sucesso!",
"data": {
"id": 42,
"usuario_id": 7,
"nome": "Integração DCTFWeb (produção)",
"key_prefix": "ak_live_9f3b",
"expiracao": "nunca",
"data_expiracao": null,
"ativo": false,
"escopo_global": false,
"criado_em": "2026-07-03T09:15:00-03:00",
"ultimo_uso": "2026-07-05T14:22:00-03:00",
"scopes": []
}
}Revogar sem apagar
Para desativar uma chave sem removê-la da base, use ativo: false. É a forma recomendada de revogar uma credencial preservando o histórico de auditoria.
Escopo: api_keys:write
DELETE /api-keys/{api_key_id}
Remove permanentemente uma API Key. Exige propriedade da chave (require_api_key_ownership), salvo perfil administrador/diretoria.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
api_key_id | int | path | sim | ID da chave |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "API Key removida com sucesso!",
"data": null
}Escopo: api_keys:write
GET /api-keys/{api_key_id}/scopes
Lista os escopos associados a uma API Key, junto do indicador escopo_global. Exige propriedade da chave (require_api_key_ownership), salvo perfil administrador/diretoria.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
api_key_id | int | path | sim | ID da chave |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Escopos da API Key listados com sucesso.",
"data": {
"escopo_global": false,
"scopes": [
{ "id": 3, "codigo": "customers:read", "recurso": "customers", "acao": "read" },
{ "id": 8, "codigo": "lembretes:write", "recurso": "lembretes", "acao": "write" }
]
}
}Escopo: api_keys:read
PUT /api-keys/{api_key_id}/scopes
Substitui (não incrementa) a lista de escopos de uma API Key numa única transação atômica, junto com a flag escopo_global. Exige propriedade da chave, salvo perfil administrador/diretoria. escopo_global = true só é aceito de perfil administrador/diretoria e um usuário funcionario só pode atribuir scope_ids que já possua (escopos além dos seus geram 403).
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
api_key_id | int | path | sim | ID da chave |
Corpo da requisição: ScopeAssignRequest com escopo_global (bool) e scope_ids (lista completa que substitui a anterior).
Request
{
"escopo_global": false,
"scope_ids": [3, 8]
}Response 200 OK
{
"success": true,
"message": "Escopos da API Key atualizados com sucesso.",
"data": {
"escopo_global": false,
"scopes": [
{ "id": 3, "codigo": "customers:read", "recurso": "customers", "acao": "read" },
{ "id": 8, "codigo": "lembretes:write", "recurso": "lembretes", "acao": "write" }
]
}
}Escopo: api_keys:write
Schemas
ApiKeyCreate
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
nome | str | sim | Nome descritivo da chave (identifica a integração). |
expiracao | str | não | Política de expiração. Default "nunca". |
escopo_global | bool | não | Concede acesso global. Default false. Somente perfil administrador/diretoria pode definir true. |
scope_ids | list[int] | não | IDs dos escopos concedidos. Default []. Limitado aos escopos do próprio usuário. |
ApiKeyUpdate
Todos os campos são opcionais; apenas os enviados são atualizados.
| Campo | Tipo | Observações |
|---|---|---|
nome | str | Novo nome descritivo da chave. |
ativo | bool | Ativa (true) ou revoga (false) a chave. |
ApiKeyRead
Objeto de leitura devolvido nas listagens e no detalhamento. Nunca contém o segredo em texto puro.
| Campo | Tipo | Notas |
|---|---|---|
id | int | Identificador da chave. |
usuario_id | int | Usuário dono da chave. |
nome | str | Nome descritivo. |
key_prefix | str | Prefixo público da chave (para identificação; não é o segredo). |
expiracao | str | Política de expiração (ex.: "nunca"). |
data_expiracao | datetime | null | Data de expiração calculada, quando houver. |
ativo | bool | Se a chave está ativa. |
escopo_global | bool | Se possui acesso global. Default false. |
criado_em | datetime | null | Timestamp de criação. |
ultimo_uso | datetime | null | Último uso registrado (null se nunca usada). |
scopes | list[ScopeRead] | Escopos associados à chave. |
ApiKeyCreatedResponse
Estende ApiKeyRead com um único campo adicional, retornado apenas na criação:
| Campo | Tipo | Notas |
|---|---|---|
api_key | str | O segredo em texto puro. Exibido uma só vez; não é recuperável depois. |
ScopeRead
Usado dentro de ApiKeyRead.scopes e nas respostas de escopos.
| Campo | Tipo | Notas |
|---|---|---|
id | int | Identificador do escopo. |
codigo | str | Código canônico (ex.: customers:read). |
recurso | str | Recurso (ex.: customers, api_keys). |
acao | str | Ação (read ou write). |
descricao | str | null | Descrição legível do escopo. |
tag_openapi | str | null | Tag OpenAPI para agrupamento em telas de UI. |
criado_em | datetime | null | Timestamp de criação do escopo. |
ScopeAssignRequest
Payload de PUT /api-keys/{api_key_id}/scopes (o mesmo formato é usado ao atribuir escopos a usuários).
| Campo | Tipo | Observações |
|---|---|---|
escopo_global | bool | Default false. Somente perfil administrador/diretoria pode definir true. |
scope_ids | list[int] | Conjunto completo de escopos (substitui o anterior). Default []. |
Notas
Nunca exponha ao gateway MCP
Reforçando: os endpoints de API Keys são administrativos e permitem escalada de privilégios (criar chaves, ampliar escopos, revogar credenciais). Jamais inclua api_keys:read ou api_keys:write numa API Key destinada ao MCP ou a clientes de IA.
Guarde o segredo na criação
O segredo (api_key) só aparece na resposta do POST /api-keys/. Não há endpoint para recuperá-lo. Perdeu? Revogue (PUT com ativo: false) ou apague (DELETE) e gere uma nova.
- Toda resposta segue o envelope
{ success, message, data }(ou{ success: false, message, details }em erro). GET /api-keys/meé declarado antes da rota dinâmicaGET /api-keys/{api_key_id}, entãomeé resolvido como rota estática (e não interpretado como umapi_key_id).- O
PUT /api-keys/{api_key_id}/scopessubstitui o conjunto inteiro de escopos - para adicionar um escopo, envie a lista completa desejada, não apenas o novo item. - A gestão de escopos disponíveis vive no domínio Scopes; aqui apenas os associamos a uma chave.