LIVE · CATENA D'AUDIT · UE
SISTEMA · 99,99% UPTIME
v 1.0 ↗ FATTO IN UE

Paginazione + idempotenza

Paginazione a cursore su ogni endpoint di lista; Idempotency-Key su ogni endpoint che modifica lo stato. Due pattern da interiorizzare una volta; ogni endpoint li segue.

Paginazione a cursore

Tutti gli endpoint di lista (GET /api/v1/public/sessions, /evidence, /whiteboards, ecc.) restituiscono un envelope:

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

Come paginare

  1. Invia la prima richiesta senza il parametro cursor.
  2. Se has_more è true, passa next_cursor testualmente come parametro query cursor nella richiesta successiva.
  3. Ripeti finché has_more è 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_..."

Limiti

ParamDefaultMax
limit25100

Valori di limit più alti riducono il numero di round-trip ma aumentano la dimensione del payload per risposta + il tempo di serializzazione. Il default 25 è adatto all'uso in UI; i job batch notturni tipicamente passano 100.

Forma del cursore

Il cursore è opaco per i client — è un blob JSON codificato in base64 che codifica la posizione nel queryset sottostante. Non fare il parsing né costruire cursori; passali semplicemente testualmente. La forma non è stabile tra le versioni dell'API.

Ordinamento

L'ordinamento predefinito è created_at DESC (più recenti prima) per ogni endpoint di lista. È anche l'ordine in cui il cursore avanza — camminerai dal più recente al più vecchio man mano che pagini.

Helper degli SDK

Entrambi gli SDK includono un async-iterator trasparente che pagina per te:

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

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

Idempotenza

Ogni endpoint che modifica lo stato accetta un header Idempotency-Key. Passa una chiave univoca (tipicamente un UUID) per operazione logica; un retry con la stessa chiave restituisce la risposta in cache senza ricreare la risorsa.

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"}'

Finestra di cache

Le risposte in cache vivono per 24 ore. Il replay dopo 24h con la stessa chiave crea una nuova risorsa — tratta la chiave come valida solo per la durata del tuo retry loop.

Scoping

Le chiavi sono vincolate a (credential, endpoint, method):

  • Un retry dalla stessa credenziale allo stesso endpoint con la stessa chiave restituisce la risposta in cache.
  • Una credenziale diversa che usa la stessa chiave crea una nuova risorsa (la tratta come una chiamata nuova).
  • La stessa chiave su un endpoint diverso crea una nuova risorsa (slot di cache separato).

Cosa viene messo in cache

Solo le risposte riuscite (2xx). Una richiesta fallita non avvelena la cache — il tuo prossimo retry con la stessa chiave ottiene un nuovo tentativo.

Echo dell'header

Le risposte idempotenti riuscite restituiscono la chiave nell'header di risposta Idempotency-Key — utile per logging / correlazione.

Generare le chiavi

Usa qualsiasi cosa sia globalmente univoca per operazione logica:

  • crypto.randomUUID() in Node 19+
  • uuid.uuid4() in Python
  • L'id del tuo processo di business (es. numero sinistro + timestamp) se vuoi tracce leggibili dall'uomo nei log

Helper degli 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()))

Cosa c'è dopo

  • Errori + rate limit — cosa succede quando la paginazione o i loop di retry vanno storti
  • API Sessioni — primo endpoint su cui applicare entrambi i pattern