NA ŻYWO · ŁAŃCUCH AUDYTU · UE
SYSTEM · 99,99% DOSTĘPNOŚĆ
v 1.0 ↗ WYPRODUKOWANO W UE

Paginacja + idempotencja

Paginacja kursorowa na każdym endpoincie listującym; Idempotency-Key na każdym endpoincie zmieniającym stan. Dwa wzorce do przyswojenia raz; każdy endpoint się nimi kieruje.

Paginacja kursorowa

Wszystkie endpointy listujące (GET /api/v1/public/sessions, /evidence, /whiteboards itp.) zwracają kopertę:

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

Jak stronicować

  1. Wyślij pierwsze żądanie bez parametru cursor.
  2. Jeśli has_more to true, przekaż next_cursor dosłownie jako parametr zapytania cursor w następnym żądaniu.
  3. Powtarzaj, aż has_more będzie 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_..."

Limity

ParametrDomyślnieMaks.
limit25100

Wyższe wartości limit redukują liczbę round-tripów, ale zwiększają rozmiar ładunku na odpowiedź + czas serializacji. Domyślne 25 nadaje się do użytku w UI; nocne zadania wsadowe zwykle przekazują 100.

Kształt kursora

Kursor jest nieprzejrzysty dla klientów — to zakodowany w base64 blob JSON kodujący pozycję w bazowym queryset. Nie parsuj ani nie konstruuj kursorów; po prostu przekazuj je dosłownie. Kształt nie jest stabilny między wersjami API.

Sortowanie

Domyślne sortowanie to created_at DESC (najnowsze pierwsze) dla każdego endpointu listującego. To także kierunek, w którym posuwa się kursor — stronicując, będziesz przechodzić od najnowszych do najstarszych.

Helpery SDK

Oba SDK dostarczają przezroczysty iterator asynchroniczny, który stronicuje za Ciebie:

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

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

Idempotencja

Każdy endpoint zmieniający stan przyjmuje nagłówek Idempotency-Key. Przekaż unikalny klucz (zwykle UUID) na operację logiczną; ponowienie z tym samym kluczem zwraca zbuforowaną odpowiedź bez ponownego tworzenia zasobu.

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

Okno bufora

Zbuforowane odpowiedzi żyją przez 24 godziny. Powtórzenie po 24 h z tym samym kluczem tworzy nowy zasób — traktuj klucz jako ważny tylko na czas trwania Twojej pętli ponawiania.

Zakresowanie

Klucze są zakresowane do (credential, endpoint, method):

  • Ponowienie z tego samego poświadczenia do tego samego endpointu z tym samym kluczem zwraca zbuforowaną odpowiedź.
  • Inne poświadczenie używające tego samego klucza tworzy nowy zasób (traktuje je jako świeże wywołanie).
  • Ten sam klucz na innym endpoincie tworzy nowy zasób (oddzielny slot bufora).

Co jest buforowane

Tylko udane odpowiedzi (2xx). Nieudane żądanie nie zatruwa bufora — Twoje następne ponowienie z tym samym kluczem otrzymuje świeżą próbę.

Echo nagłówka

Udane odpowiedzi idempotentne odbijają klucz w nagłówku odpowiedzi Idempotency-Key — przydatne do logowania / korelacji.

Generowanie kluczy

Użyj czegokolwiek, co jest globalnie unikalne na operację logiczną:

  • crypto.randomUUID() w Node 19+
  • uuid.uuid4() w Pythonie
  • Twój identyfikator procesu biznesowego (np. numer roszczenia + znacznik czasu), jeśli chcesz czytelnych dla człowieka śladów w logach

Helpery 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()))

Co dalej