LIVE · AUDIT-KETEN · EU-GEHOST
SYSTEEM · 99,99% UPTIME
v 1.0 ↗ GEMAAKT IN DE EU

Sessions API

Een Session is één inspectie. Maak er een, genereer een veldgebruiker-uitnodiging, leg bewijs vast, beëindig hem. Al het andere hangt aan deze resource.

Het Session-object

{
  "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"
}
StatusBetekenis
createdSession-rij bestaat; nog niemand is binnengekomen.
openVeldgebruiker is binnengekomen; sessie is live.
recordingOpname bezig (optioneel, door operator gestart).
closedSessie beëindigd. Ketenkop verankerd bij TSA; rapporten beschikbaar.
expiredGeplande sessie waar niemand binnen de TTL is binnengekomen.

Een sessie aanmaken

POST /api/v1/public/sessions — scope 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"
  }'

Retourneert het zojuist aangemaakte Session-object (HTTP 201).

Body-velden

VeldTypeVereistOpmerkingen
notesstringneeZichtbaar voor de operator. Weergegeven in uitnodigingsmails.
scheduled_forISO 8601neeToekomstige datum activeert herinneringsmails 24u + 1u van tevoren. Weglaten voor "nu starten".
localestringneeEen van de 14 ondersteunde locales. Bepaalt de taal van de SPA + het PDF-rapport. Standaard de voorkeur van de org.
campaignUUIDneeOptionele FK naar een Campaign voor gebundelde rapportage.

Sessies lijsten

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

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

Cursor-gepagineerd. Geef cursor uit de vorige response's next_cursor mee om te pagineren.

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

Een sessie ophalen

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

Een sessie beëindigen

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

Sluit de sessie, activeert de ketenkopverankering bij alle geconfigureerde TSA's, en start de nabewerking van de opname als er een opname liep. Idempotent — aanroepen op een reeds gesloten sessie retourneert het gesloten Session-object zonder opnieuw te verankeren.

Een veldgebruiker-uitnodiging genereren

POST /api/v1/public/sessions/{session_id}/participants — scope 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"
}

De join_url en otp_code worden precies één keer getoond in de response. Tokens zijn IP/UA-gebonden, eenmalig en in de tijd begrensd.

Tweefactor-join (OTP)

Wanneer u ten minste een van recipient_email of recipient_phone opgeeft, genereert het platform automatisch een 6-cijferige numerieke OTP en verstuurt die op de bijbehorende kana(a)l(en) in een apart bericht dan de join-URL — defence-in-depth zodat een doorgestuurde e-mail of sms niet beide factoren tegelijk lekt. De platte code wordt ook geretourneerd in de response ( otp_code) zodat u die handmatig opnieuw kunt delen als bezorging mislukt.

Aan de veldkant toont de SPA de OTP-prompt bij de eerste inwisseling. Dien de code in via de X-Join-OTP header bij een retry van GET /v1/sessions/{id}/join/{token} — de header (niet de URL) houdt de code buiten de browsergeschiedenis en access logs.

OTP-regels:

  • 6-cijferig numeriek, in rust gehasht met SHA-256 + pepper.
  • TTL van 10 minuten vanaf afgifte.
  • 5 foute pogingen vergrendelen de uitnodiging (HTTP 423) — operator moet opnieuw uitgeven.
  • Eenmalig geverifieerd bij de eerste inwisseling; herinwisseling vanaf hetzelfde IP-/UA-paar slaat de gate over (het token is al gebonden).
  • Face-to-face URL-overdracht (geen recipient_email + geen recipient_phone) slaat OTP-generatie over — de URL alleen is de auth-factor. Gebruik dit alleen voor persoonlijke overdrachten.

Response-codes op GET /v1/sessions/{id}/join/{token}:

StatusBodyBetekenis
200{field_session_token, livekit, ...}OTP geslaagd (of niet vereist); veldsessie is live.
401{detail:"otp_required", channels:[...], channel_hint_email, channel_hint_phone}SPA moet het OTP-invoerformulier tonen.
401{detail:"otp_invalid", attempts_remaining}Foute code; toon resterende pogingen.
401{detail:"otp_expired"}Venster van 10 min verstreken; operator moet opnieuw uitgeven.
423{detail:"otp_locked"}5 foute pogingen; uitnodiging is dood tot heruitgave.

Veelvoorkomende fouten

StatusCodeWanneer
402billing.subscription_past_dueStripe-abonnement van de org is achterstallig.
402billing.free_plan_minutes_exhaustedGratis / Pilot-niveau heeft zijn 5 inspecties gebruikt.
403permission_deniedCredential mist sessions:write scope.
409session.already_endedPoging om een sessie te beëindigen die al gesloten is (zeldzaam — `end` is normaal idempotent).
429rate_limited60-rpm per-credential- of 600-rpm per-org-throttle bereikt. Zie X-RateLimit-Reset header.

Zie Fouten + rate limits voor de volledige vorm van de error-envelope en retry-richtlijnen.