Sessions API
En Session er én inspeksjon. Opprett en, generer en feltbruker-invitasjon, samle inn bevis, avslutt den. Alt annet henger av denne ressursen.
Session-objektet
{
"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"
} | Status | Betydning |
|---|---|
created | Session-rad finnes; ingen har blitt med ennå. |
open | Feltbruker har blitt med; økten er live. |
recording | Opptak pågår (valgfritt, operatør-utløst). |
closed | Økt avsluttet. Kjedehode forankret ved tidsstemplingsmyndighet; rapporter tilgjengelige. |
expired | Planlagt økt som ingen ble med i innenfor TTL-en. |
Opprett en økt
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"
}' Returnerer det nyopprettede Session-objektet (HTTP 201).
Body-felt
| Felt | Type | Påkrevd | Merknader |
|---|---|---|---|
notes | string | nei | Synlig for operatøren. Vises i invitasjonsepost. |
scheduled_for | ISO 8601 | nei | Fremtidig dato utløser påminnelsesepost 24t + 1t før. Utelat for "start nå". |
locale | string | nei | En av de 14 støttede lokalitetene. Styrer språket i SPA-en + PDF-rapporten. Standard er organisasjonens preferanse. |
campaign | UUID | nei | Valgfri FK til en Campaign for gruppert rapportering. |
List økter
GET /api/v1/public/sessions — scope sessions:read
curl https://app.nexbasira.com/api/v1/public/sessions?limit=25 \
-H "Authorization: Bearer nb_sec_..." Markørpaginert. Send cursor fra forrige svars next_cursor for å bla.
{
"data": [{ /* Session, Session, ... */ }],
"has_more": true,
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAy..."
} Hent en økt
GET /api/v1/public/sessions/{session_id} — scope sessions:read
Avslutt en økt
POST /api/v1/public/sessions/{session_id}/end — scope sessions:write
Lukker økten, utløser kjedehode-forankringen ved alle konfigurerte tidsstemplingsmyndigheter, og starter etterbehandling av opptak hvis et opptak var i gang. Idempotent — å kalle på en allerede lukket økt returnerer det lukkede Session-objektet uten å forankre på nytt.
Generer en feltbruker-invitasjon
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"
} Verdien join_url og otp_code vises nøyaktig én gang i svaret. Tokens er IP/UA-låst, engangsbruk og tidsavgrenset.
Tofaktor-innlogging (OTP)
Når du oppgir minst én av recipient_email eller recipient_phone, genererer plattformen automatisk en 6-sifret numerisk OTP og sender den på matchende kanal(er) i en separat melding fra innloggings-URL-en — dybdeforsvar slik at en videresendt epost eller SMS ikke lekker begge faktorene på én gang. Den rene koden returneres også i svaret ( otp_code) slik at du kan dele den manuelt på nytt hvis levering feiler.
På feltsiden viser SPA-en OTP-forespørselen ved første innløsning. Send inn koden via X-Join-OTP -hodet på en retry av GET /v1/sessions/{id}/join/{token} — hodet (ikke URL-en) holder koden ute av nettleserhistorikk og tilgangslogger.
OTP-regler:
- 6-sifret numerisk, hashet med SHA-256 + pepper i hvile.
- 10-minutters TTL fra utstedelse.
- 5 feil forsøk låser invitasjonen (HTTP 423) — operatør må utstede på nytt.
- Verifisert én gang ved første innløsning; ny innløsning fra samme IP-/UA-par hopper over porten (tokenet er allerede låst).
- Ansikt-til-ansikt URL-overlevering (ingen
recipient_email+ ingenrecipient_phone) hopper over OTP-generering — URL-en alene er autentiseringsfaktoren. Bruk dette kun for personlige overleveringer.
Svarkoder på GET /v1/sessions/{id}/join/{token}:
| Status | Body | Betydning |
|---|---|---|
| 200 | {field_session_token, livekit, ...} | OTP bestått (eller ikke påkrevd); feltøkten er live. |
| 401 | {detail:"otp_required", channels:[...], channel_hint_email, channel_hint_phone} | SPA-en bør vise OTP-inntastingsskjemaet. |
| 401 | {detail:"otp_invalid", attempts_remaining} | Feil kode; vis gjenstående forsøk. |
| 401 | {detail:"otp_expired"} | 10-minutters vindu utløpt; operatør må utstede på nytt. |
| 423 | {detail:"otp_locked"} | 5 feil forsøk; invitasjonen er død til ny utstedelse. |
Vanlige feil
| Status | Code | Når |
|---|---|---|
| 402 | billing.subscription_past_due | Organisasjonens Stripe-abonnement er forfalt. |
| 402 | billing.free_plan_minutes_exhausted | Free-/Pilot-nivået har brukt sine 5 inspeksjoner. |
| 403 | permission_denied | Legitimasjonen mangler sessions:write scope. |
| 409 | session.already_ended | Prøver å avslutte en økt som allerede er lukket (sjeldent — `end` er normalt idempotent). |
| 429 | rate_limited | 60-rpm per-legitimasjon eller 600-rpm per-organisasjon struping nådd. Se X-RateLimit-Reset -hodet. |
Se Feil + hastighetsgrenser for den fulle feilkonvoluttformen og retry-veiledningen.