Pular para o conteúdo principal

Princípios das APIs

Para quem é esta página

Engenheiros back-end e front-end. Para endpoints específicos, use o menu lateral.

Convenções Gerais

  • Versioning: prefixo /api/v1/
  • Autenticação: Authorization: Bearer {JWT} em todas as rotas protegidas
  • Content-Type: application/json
  • Datas: ISO 8601 com timezone UTC (2026-01-15T10:30:00Z)
  • IDs: UUIDs v4 em todos os recursos

Envelope de Resposta

Recurso único

{
"data": { "id": "...", "status": "rascunho" },
"meta": { "request_id": "uuid", "timestamp": "2026-01-15T10:30:00Z" }
}

Lista paginada

{
"data": [...],
"meta": {
"cursor_next": "opaque-cursor",
"cursor_prev": null,
"total_count": 150,
"has_more": true,
"page_size": 20
}
}

Erro

{
"error": {
"code": "CAR-004",
"message": "Dados de entrada inválidos",
"details": [
{ "field": "municipio_ibge", "code": "invalid_format", "message": "Deve ter 7 dígitos" }
]
}
}

Paginação Cursor-Based

Por que cursor em vez de offset?

Paginação com OFFSET é instável — novos registros mudam a posição dos itens. Cursor-based é estável e mais performática para tabelas grandes.

GET /api/v1/processos?page_size=20
→ meta.cursor_next = "eyJpZCI6IjU1MGU4..."

GET /api/v1/processos?page_size=20&cursor=eyJpZCI6IjU1MGU4...
→ próxima página

Rate Limiting

RoleGeralUploadAssistente
Produtor Rural60 req/min5 req/min20 req/min
Responsável Técnico (RT)120 req/min15 req/min20 req/min
Analista200 req/min30 req/min20 req/min
Adminsem limitesem limitesem limite

Headers de resposta: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset

Idempotência

Operações críticas e irreversíveis aceitam o header Idempotency-Key:

POST /api/v1/processos/{id}/submeter
Idempotency-Key: meu-key-unico-123

Mesma key com mesma requisição retorna o mesmo resultado sem executar duas vezes.

Ver também