API REST
Endpoints, autenticação, idempotência e padrões de erro.
Convenções
- Base:
/v1/*.
- Content-Type:
application/json.
- Autenticação: header
Authorization: Bearer <jwt>. Endpoints públicos: /v1/auth/* (exceto /me que requer auth).
- Idempotência: mutações sensíveis aceitam header
Idempotency-Key (string única; replays retornam resposta original).
- Request ID: resposta inclui
X-Request-Id usado em logs e audit.
- Erros:
{ "error": { "code": "...", "message": "...", "details": {...} } }.
Autenticação
| Método | Endpoint | Descrição |
| POST | /v1/auth/login | E-mail + senha (+ org_slug opcional). |
| POST | /v1/auth/login-rfid | RFID hex + org_slug. |
| POST | /v1/auth/bootstrap | Cria primeira organização (uma vez por tenant). |
| GET | /v1/auth/accessible-orgs | Lista orgs que o usuário pode acessar (matriz + filiais). |
| POST | /v1/auth/switch-org | Re-emite JWT para outra org acessível. |
| GET | /v1/me | Perfil do usuário corrente + dados da org. |
Rotas administrativas
| Endpoint | Descrição |
/v1/orgs | GET / PATCH da org corrente; GET /stats para indicadores. |
/v1/branches | GET / POST / PATCH / DELETE filiais; POST /:id/grant-access. |
/v1/users | CRUD de usuários. |
/v1/sectors · /v1/locations · /v1/suppliers · /v1/specialties · /v1/packaging | CRUDs de cadastros mestres. |
/v1/item-models · /v1/items | Catálogo + inventário. |
/v1/kit-templates · /v1/kits | Templates e instâncias de kit. |
/v1/equipments | Autoclaves, lavadoras, ultrassônicas. |
/v1/labels | GET /{kit,item,batch}/:id/zpl, /test-print, POST /render. |
/v1/audit | Consulta filtrável (ADMIN/SUPERVISOR). |
/v1/dashboard | KPIs por org. |
Rotas operacionais
| Endpoint | Descrição |
POST /v1/lifecycle/scan | Único ponto de entrada para barcode/QR no chão operacional. FSM decide aceitar ou rejeitar. |
POST /v1/lifecycle/expurgo/reconcile | Submete conferência cega do expurgo. |
/v1/batches | CRUD de lotes de esterilização. |
/v1/quarantine | Lista e release (com re-auth supervisor). |
/v1/recall | Disparo do botão de pânico e acompanhamento. |
/v1/surgery | Point-of-care (vínculo kit ↔ paciente). |
/v1/uploads | Upload de fotos / laudos para R2. |
Códigos de erro padrão
| HTTP | code | Quando ocorre |
| 400 | invalid_body | Validação Zod falhou. |
| 401 | invalid_credentials / missing_token / unauthorized | Auth falhou ou token inválido. |
| 403 | forbidden | RBAC insuficiente. |
| 404 | not_found | Recurso inexistente ou fora da org. |
| 409 | fsm_violation / slug_taken / cannot_delete_hq | Regra de negócio violada. |
| 423 | account_locked | 5 tentativas erradas em 15 min. |
| 429 | rate_limited | Excedeu janela de rate-limit. |
| 500 | internal_error | Erro inesperado; inclui request_id. |
Exemplo: troca de organização
POST /v1/auth/switch-org
Authorization: Bearer eyJ...
Content-Type: application/json
{ "target_org_id": "b1a2c3..." }
200 OK
{
"token": "eyJ...",
"expires_in": 28800,
"org": { "id": "b1a2c3...", "slug": "filial-sp", "legal_name": "Filial SP", "org_type": "BRANCH" }
}
Exemplo: lifecycle scan
POST /v1/lifecycle/scan
Authorization: Bearer eyJ...
Idempotency-Key: scan-2026-05-28-001
Content-Type: application/json
{
"barcode": "KIT-CARDIO-001",
"target_phase": "PREPARO",
"context": { "workstation": "BANCADA-3" }
}
200 OK
{
"ok": true,
"entity": "KIT_INSTANCE",
"entity_id": "k1a2b3...",
"new_status": "PREPARO",
"event_id": "e9f8..."
}