Paginierung + Idempotenz
Cursor-Paginierung auf jedem List-Endpoint; Idempotency-Key auf jedem zustandsverändernden Endpoint. Zwei Muster, die man sich einmal verinnerlicht; jeder Endpoint folgt ihnen.
Cursor-Paginierung
Alle List-Endpoints (GET /api/v1/public/sessions, /evidence, /whiteboards usw.) geben ein Envelope zurück:
{
"data": [
{ /* resource */ },
{ /* resource */ }
],
"has_more": true,
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0yMVQxNDoyMSswMDowMCJ9"
} Wie man paginiert
- Setzen Sie den ersten Request ohne
cursor-Param ab. - Wenn
has_moretrueist, übergeben Sienext_cursorwortgetreu alscursor-Query-Param beim nächsten Request. - Wiederholen Sie, bis
has_morefalseist.
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_..." Limits
| Param | Standard | Max |
|---|---|---|
limit | 25 | 100 |
Höhere limit-Werte reduzieren die Anzahl der Round-Trips, erhöhen aber die Payload-Größe pro Response + die Serialisierungszeit. Der Standard 25 eignet sich für die UI-Nutzung; nächtliche Batch-Jobs übergeben typischerweise 100.
Cursor-Form
Der Cursor ist für Clients opak — es ist ein base64-kodierter JSON-Blob, der die Position im zugrunde liegenden Queryset kodiert. Parsen oder konstruieren Sie keine Cursor; übergeben Sie sie einfach wortgetreu. Die Form ist über API-Versionen hinweg nicht stabil.
Sortierung
Die Standardsortierung ist created_at DESC (neueste zuerst) für jeden List-Endpoint. Das ist auch die Reihenfolge, in der der Cursor voranschreitet — Sie laufen beim Paginieren vom Neuesten zum Ältesten.
SDK-Helper
Beide SDKs liefern einen transparenten Async-Iterator, der für Sie paginiert:
// @nexbasira/node
for await (const session of nb.sessions.list({ limit: 100 })) {
// ...
}
// nexbasira (Python)
for session in nb.sessions.iter(limit=100):
... Idempotenz
Jeder zustandsverändernde Endpoint akzeptiert einen Idempotency-Key-Header. Übergeben Sie einen eindeutigen Key (typischerweise eine UUID) pro logischer Operation; ein Retry mit demselben Key gibt die gecachte Response zurück, ohne die Ressource neu zu erstellen.
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"}' Cache-Fenster
Gecachte Responses leben 24 Stunden. Ein Replay nach 24 h mit demselben Key erstellt eine neue Ressource — behandeln Sie den Key nur für die Dauer Ihrer Retry-Schleife als gültig.
Scoping
Keys sind auf (credential, endpoint, method) beschränkt:
- Ein Retry vom selben Credential zum selben Endpoint mit demselben Key gibt die gecachte Response zurück.
- Ein anderes Credential mit demselben Key erstellt eine neue Ressource (behandelt es als frischen Call).
- Derselbe Key auf einem anderen Endpoint erstellt eine neue Ressource (separater Cache-Slot).
Was gecacht wird
Nur erfolgreiche Responses (2xx). Ein fehlgeschlagener Request vergiftet den Cache nicht — Ihr nächster Retry mit demselben Key erhält einen frischen Versuch.
Header-Echo
Erfolgreiche idempotente Responses spiegeln den Key im Idempotency-Key-Response-Header zurück — nützlich fürs Logging / die Korrelation.
Keys generieren
Nutzen Sie alles, was pro logischer Operation global eindeutig ist:
crypto.randomUUID()in Node 19+uuid.uuid4()in Python- Ihre Geschäftsprozess-ID (z. B. Schadennummer + Zeitstempel), wenn Sie menschenlesbare Traces in den Logs wünschen
SDK-Helper
// @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())) Was als Nächstes kommt
- Fehler + Rate-Limits — was passiert, wenn Paginierung oder Retry-Schleifen schiefgehen
- Sessions-API — erster Endpoint, um beide Muster anzuwenden