LIVE · LANȚ DE AUDIT · UE
SISTEM · 99,99% UPTIME
v 1.0 ↗ FĂCUT ÎN UE

API Sesiuni

O Sesiune este o inspecție. Creați una, generați o invitație pentru utilizatorul de teren, capturați probe, încheiați-o. Tot restul se sprijină pe această resursă.

Obiectul Session

{
  "id": "0c8f4d2e-1a3b-4c5d-9e7f-1234567890ab",
  "status": "open",
  "operator_email": "ops@yourco.com",
  "scheduled_for": "2026-05-23T10:00:00Z",
  "started_at": "2026-05-23T10:00:14Z",
  "ended_at": null,
  "notes": "Vehicle damage — claim CL-2026-0042",
  "locale": "fr",
  "consent_state": { "camera": "granted", "gps": "granted" },
  "campaign": null,
  "created_at": "2026-05-21T14:21:00Z",
  "updated_at": "2026-05-23T10:00:14Z"
}
StareSemnificație
createdRândul sesiunii există; nimeni nu s-a alăturat încă.
openUtilizatorul de teren s-a alăturat; sesiunea este live.
recordingÎnregistrare în curs (opțională, declanșată de operator).
closedSesiune încheiată. Capul lanțului ancorat la TSA; rapoarte disponibile.
expiredSesiune planificată la care nimeni nu s-a alăturat în timpul TTL.

Creați o sesiune

POST /api/v1/public/sessions — permisiune sessions:write

curl -X POST https://app.nexbasira.com/api/v1/public/sessions \
  -H "Authorization: Bearer nb_sec_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "notes": "Vehicle damage — claim CL-2026-0042",
    "scheduled_for": "2026-05-23T10:00:00Z",
    "locale": "fr"
  }'

Returnează obiectul Session nou creat (HTTP 201).

Câmpuri ale corpului

CâmpTipObligatoriuNote
notesstringnuVizibil pentru operator. Afișat în e-mailurile de invitație.
scheduled_forISO 8601nuO dată viitoare declanșează e-mailuri de reamintire cu 24h + 1h înainte. Omiteți pentru „start acum”.
localestringnuUna dintre cele 14 locale suportate. Determină limba SPA + a raportului PDF. Implicit, preferința organizației.
campaignUUIDnuFK opțional către o Campanie pentru raportare grupată.

Listați sesiunile

GET /api/v1/public/sessions — permisiune sessions:read

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

Paginat prin cursor. Transmiteți cursor cu next_cursor din răspunsul anterior pentru a naviga între pagini.

{
  "data": [{ /* Session, Session, ... */ }],
  "has_more": true,
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAy..."
}

Obțineți o sesiune

GET /api/v1/public/sessions/{session_id} — permisiune sessions:read

Încheiați o sesiune

POST /api/v1/public/sessions/{session_id}/end — permisiune sessions:write

Închide sesiunea, declanșează ancorarea capului de lanț la toate TSA-urile configurate și pornește postprocesarea înregistrării dacă rula o înregistrare. Idempotent — apelarea pe o sesiune deja închisă returnează obiectul Session închis fără a reancora.

Generați o invitație pentru utilizatorul de teren

POST /api/v1/public/sessions/{session_id}/participants — permisiune participants:write

curl -X POST https://app.nexbasira.com/api/v1/public/sessions/0c8f.../participants \
  -H "Authorization: Bearer nb_sec_..." \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_first_name": "Alex",
    "recipient_last_name": "Garcia",
    "recipient_email": "alex@policyholder.com",
    "send_email": true,
    "ttl_minutes": 1440
  }'
{
  "id": "i-1",
  "session": "0c8f...",
  "role": "field",
  "expires_at": "2026-05-24T10:00:00Z",
  "recipient_first_name": "Alex",
  "recipient_last_name": "Garcia",
  "recipient_email": "alex@policyholder.com",
  "recipient_phone": "",
  "join_url": "https://app.nexbasira.com/join/0c8f.../?t=tok_PLAINTEXT_ONCE",
  "otp_code": "487192",
  "otp_required": true,
  "otp_expires_at": "2026-05-23T10:10:00Z",
  "created_at": "2026-05-23T10:00:00Z"
}

Atât join_url cât și otp_code sunt afișate exact o dată în răspuns. Token-urile sunt legate de IP/UA, de unică folosință și limitate în timp.

Alăturare cu doi factori (OTP)

Când furnizați cel puțin unul dintre recipient_email sau recipient_phone, platforma generează automat un OTP numeric din 6 cifre și îl trimite pe canalul (canalele) corespunzător(oare) într-un mesaj separat de URL-ul de alăturare — apărare în profunzime, astfel încât un e-mail sau SMS redirecționat să nu dezvăluie ambii factori deodată. Codul în clar este de asemenea returnat în răspuns ( otp_code) ca să îl puteți re-partaja manual dacă livrarea eșuează.

Pe partea de teren, SPA afișează solicitarea OTP la prima utilizare. Trimiteți codul prin antetul X-Join-OTP la o reîncercare a GET /v1/sessions/{id}/join/{token} — antetul (nu URL-ul) ține codul departe de istoricul browserului și de jurnalele de acces.

Reguli OTP:

  • Numeric din 6 cifre, hash-uit cu SHA-256 + pepper în repaus.
  • TTL de 10 minute de la emitere.
  • 5 încercări greșite blochează invitația (HTTP 423) — operatorul trebuie să reemită.
  • Verificat o dată la prima utilizare; reutilizarea de la aceeași pereche IP / UA sare peste verificare (token-ul este deja legat).
  • Predarea URL-ului față în față (fără recipient_email + fără recipient_phone) sare peste generarea OTP — doar URL-ul este factorul de autentificare. Folosiți asta doar pentru predări în persoană.

Coduri de răspuns pentru GET /v1/sessions/{id}/join/{token}:

StareCorpSemnificație
200{field_session_token, livekit, ...}OTP a trecut (sau nu este necesar); sesiunea de teren este live.
401{detail:"otp_required", channels:[...], channel_hint_email, channel_hint_phone}SPA ar trebui să afișeze formularul de introducere a OTP.
401{detail:"otp_invalid", attempts_remaining}Cod greșit; afișați încercările rămase.
401{detail:"otp_expired"}Fereastra de 10 min a expirat; operatorul trebuie să reemită.
423{detail:"otp_locked"}5 încercări greșite; invitația este moartă până la reemitere.

Erori frecvente

StareCodCând
402billing.subscription_past_dueAbonamentul Stripe al organizației are plata restantă.
402billing.free_plan_minutes_exhaustedNivelul Gratuit / Pilot și-a folosit cele 5 inspecții.
403permission_deniedCredențialul nu are sessions:write permisiune.
409session.already_endedÎncercare de a încheia o sesiune deja închisă (rar — `end` este de obicei idempotent).
429rate_limitedLimită de 60-rpm per credențial sau 600-rpm per organizație atinsă. Vedeți antetul X-RateLimit-Reset .

Vedeți Erori + limite de rată pentru forma completă a plicului de eroare și ghidul de reîncercare.