EN DIRECT · AUDIT CHAÎNÉ · ÉDR UE
SYSTÈME · 99,99% DISPONIBILITÉ
v 1.0 ↗ FAIT EN UE

Pagination + idempotence

Pagination par curseur sur chaque endpoint de listage ; Idempotency-Key sur chaque endpoint modifiant l'état. Deux patterns à intégrer une fois pour toutes ; chaque endpoint les suit.

Pagination par curseur

Tous les endpoints de listage (GET /api/v1/public/sessions, /evidence, /whiteboards, etc.) renvoient une enveloppe :

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

Comment paginer

  1. Émettez la première requête sans paramètre cursor.
  2. Si has_more vaut true, passez next_cursor tel quel comme paramètre de requête cursor à la requête suivante.
  3. Répétez jusqu'à ce que has_more vaille 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

ParamètrePar défautMax
limit25100

Des valeurs de limit plus élevées réduisent le nombre d'allers-retours mais augmentent la taille du payload par réponse + le temps de sérialisation. La valeur par défaut de 25 convient à un usage UI ; les batchs nocturnes passent généralement 100.

Forme du curseur

Le curseur est opaque pour les clients — c'est un blob JSON encodé en base64 qui code la position dans le queryset sous-jacent. N'analysez pas et ne construisez pas de curseurs ; passez-les simplement tels quels. La forme n'est pas stable d'une version d'API à l'autre.

Ordre

L'ordre par défaut est created_at DESC (les plus récents d'abord) pour chaque endpoint de listage. C'est aussi l'ordre dans lequel le curseur avance — vous parcourrez du plus récent au plus ancien au fil de la pagination.

Helpers du SDK

Les deux SDK fournissent un itérateur asynchrone transparent qui pagine pour vous :

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

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

Idempotence

Chaque endpoint modifiant l'état accepte un en-tête Idempotency-Key. Passez une clé unique (généralement un UUID) par opération logique ; une nouvelle tentative avec la même clé renvoie la réponse en cache sans recréer la ressource.

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

Fenêtre de cache

Les réponses en cache vivent 24 heures. Un rejeu après 24 h avec la même clé crée une nouvelle ressource — considérez la clé comme valable uniquement pendant la durée de votre boucle de nouvelle tentative.

Portée

Les clés sont restreintes à (credential, endpoint, method) :

  • Une nouvelle tentative du même identifiant vers le même endpoint avec la même clé renvoie la réponse en cache.
  • Un identifiant différent utilisant la même clé crée une nouvelle ressource (traitée comme un nouvel appel).
  • La même clé sur un endpoint différent crée une nouvelle ressource (emplacement de cache distinct).

Ce qui est mis en cache

Seules les réponses réussies (2xx). Une requête en échec n'empoisonne pas le cache — votre prochaine tentative avec la même clé obtient un nouvel essai.

Écho de l'en-tête

Les réponses idempotentes réussies renvoient la clé en écho dans l'en-tête de réponse Idempotency-Key — utile pour la journalisation / corrélation.

Générer les clés

Utilisez tout ce qui est globalement unique par opération logique :

  • crypto.randomUUID() dans Node 19+
  • uuid.uuid4() en Python
  • L'identifiant de votre processus métier (par ex. numéro de sinistre + horodatage) si vous voulez des traces lisibles par un humain dans les logs

Helpers du 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()))

Et ensuite