Convenções

Formatos, idempotência, paginação, erros e limites de uso da API v1.

Atualizado:

O básico

  • URL base https://api.fiuit.com/v1. Mudanças incompatíveis saem como uma nova versão; mudanças aditivas (campos novos) podem chegar a qualquer momento, então ignore os campos que você não conhece.
  • JSON na entrada e na saída (Content-Type: application/json).
  • Datas em ISO 8601 com offset (2026-10-15T09:45:00-03:00). São guardadas em UTC.
  • Valores em centavos inteiros mais currency (BRL, ARS, PYG, USD).
  • Os IDs são strings opacas. Campos sem valor chegam como null explícito.
  • O contrato legível por máquina é packages/openapi/openapi.yaml (OpenAPI 3.1) e as novidades recentes resumem o que é novo.

Idempotência

POST /holds, POST /holds/{id}/confirm, POST /bookings, POST /bookings/{id}/reschedule e POST /bookings/{id}/actions/{key} levam o header Idempotency-Key (por exemplo um UUID). Repetir uma requisição com a mesma chave em até 24 horas devolve a resposta original. Reusar a chave com outro body devolve 422 com code: "idempotency_conflict".

POST /customers aceita Idempotency-Key de forma opcional. POST /webhook-endpoints não o admite, porque sua resposta contém o segredo.

Paginação

Os endpoints de listagem usam cursores:

curl "https://api.fiuit.com/v1/bookings?limit=50" -H "Authorization: Bearer $WAGEND_KEY"
# → { "data": [...], "next_cursor": "eyJpZCI6..." }
curl "https://api.fiuit.com/v1/bookings?limit=50&cursor=eyJpZCI6..." -H "Authorization: Bearer $WAGEND_KEY"

Quando next_cursor é null, não há mais páginas.

Erros

Os erros seguem a RFC 9457 (application/problem+json):

{
  "type": "https://fiuit.com/docs/api/conventions#errors",
  "title": "Slot no longer available",
  "status": 409,
  "code": "slot_taken",
  "alternatives": [{ "start": "2026-10-15T10:15:00-03:00", "end": "2026-10-15T10:45:00-03:00" }]
}
codeStatusQuando
validation_error422Falhou a validação do body ou dos parâmetros
invalid_api_key401Chave ausente, inválida ou revogada
idempotency_key_required400Falta o header Idempotency-Key em uma operação que o exige
insufficient_scope403A chave não tem o scope
not_found404Id desconhecido (ou de outro projeto)
slot_taken409Outra pessoa pegou o horário
already_claimed409Outra pessoa da equipe pegou antes a tarefa da fila
customer_exists409Já existe um cliente com esse telefone
invalid_transition409Por exemplo confirmar um agendamento cancelado
version_conflict409Alguém editou antes o mesmo recurso (versão desatualizada)
hold_expired410A pré-reserva venceu antes de confirmar
idempotency_conflict422Mesma chave, body diferente
rate_limited429Requisições demais

Toda resposta de erro traz code: use-o para decidir o que fazer, não o texto do title.

Limites de uso

Os limites valem por chave e por projeto (um balde com rajada de 120 requisições e recarga de 2 por segundo). Cada resposta traz RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset. Diante de um 429, espere Retry-After segundos.