AO VIVO · AUDIT CHAIN · UE
SISTEMA · 99,99% DISPONIBILIDADE
v 1.0 ↗ FEITO NA UE

Paginação + idempotência

Paginação por cursor em cada endpoint de listagem; Idempotency-Key em cada endpoint que altera estado. Dois padrões a interiorizar uma vez; cada endpoint segue-os.

Paginação por cursor

Todos os endpoints de listagem (GET /api/v1/public/sessions, /evidence, /whiteboards, etc.) devolvem um envelope:

{
  "data": [
    { /* resource */ },
    { /* resource */ }
  ],
  "has_more": true,
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0yMVQxNDoyMSswMDowMCJ9"
}

Como paginar

  1. Emita o primeiro request sem o param cursor.
  2. Se has_more for true, passe next_cursor tal como está como query param cursor no request seguinte.
  3. Repita até has_more ser false.
curl "https://app.nexbasira.com/api/v1/public/sessions?limit=25" \
  -H "Authorization: Bearer nb_sec_..."

# response includes next_cursor: "eyJjcmVhdGVkX2F0Ijo..."

curl "https://app.nexbasira.com/api/v1/public/sessions?limit=25&cursor=eyJjcmVhdGVkX2F0Ijo..." \
  -H "Authorization: Bearer nb_sec_..."

Limites

ParamPor defeitoMáx.
limit25100

Valores mais altos de limit reduzem o número de idas e voltas mas aumentam o tamanho do payload por resposta + o tempo de serialização. O valor por defeito 25 é adequado para uso em UI; os trabalhos em lote noturnos passam tipicamente 100.

Forma do cursor

O cursor é opaco para os clientes — é um blob JSON codificado em base64 que codifica a posição no queryset subjacente. Não faça o parse nem construa cursores; passe-os apenas tal como estão. A forma não é estável entre versões da API.

Ordenação

A ordenação por defeito é created_at DESC (mais recente primeiro) para cada endpoint de listagem. É também a ordem em que o cursor avança — vai percorrer do mais recente ao mais antigo à medida que pagina.

Helpers do SDK

Ambos os SDKs incluem um async-iterator transparente que pagina por si:

// @nexbasira/node
for await (const session of nb.sessions.list({ limit: 100 })) {
  // ...
}

// nexbasira (Python)
for session in nb.sessions.iter(limit=100):
    ...

Idempotência

Cada endpoint que altera estado aceita um cabeçalho Idempotency-Key. Passe uma chave única (tipicamente um UUID) por operação lógica; uma retentativa com a mesma chave devolve a resposta em cache sem recriar o recurso.

curl -X POST https://app.nexbasira.com/api/v1/public/sessions \
  -H "Authorization: Bearer nb_sec_..." \
  -H "Idempotency-Key: 01HGAB7T8X3PVT3HKEXAMPLE" \
  -H "Content-Type: application/json" \
  -d '{"notes": "Vehicle damage CL-2026-0042"}'

Janela de cache

As respostas em cache vivem durante 24 horas. Um replay após 24h com a mesma chave cria um novo recurso — trate a chave como válida apenas durante o seu ciclo de retentativas.

Scoping

As chaves têm scope em (credential, endpoint, method):

  • Uma retentativa da mesma credencial para o mesmo endpoint com a mesma chave devolve a resposta em cache.
  • Uma credencial diferente a usar a mesma chave cria um novo recurso (trata-a como uma chamada nova).
  • A mesma chave num endpoint diferente cria um novo recurso (slot de cache separado).

O que é colocado em cache

Apenas respostas bem-sucedidas (2xx). Um request falhado não envenena a cache — a sua próxima retentativa com a mesma chave obtém uma tentativa nova.

Eco de cabeçalho

As respostas idempotentes bem-sucedidas devolvem a chave no cabeçalho de resposta Idempotency-Key — útil para logging / correlação.

Gerar chaves

Use qualquer coisa que seja globalmente única por operação lógica:

  • crypto.randomUUID() no Node 19+
  • uuid.uuid4() em Python
  • O id do seu processo de negócio (ex.: número de sinistro + timestamp) se quiser traces legíveis por humanos nos logs

Helpers do SDK

// @nexbasira/node — pass via second arg
await nb.sessions.create(
  { notes: "..." },
  { idempotencyKey: crypto.randomUUID() },
);

// nexbasira (Python)
nb.sessions.create(notes="...", idempotency_key=str(uuid.uuid4()))

O que vem a seguir