API relací
Relace je jedna inspekce. Vytvořte ji, vygenerujte pozvánku pro uživatele v terénu, zachyťte důkazy, ukončete ji. Vše ostatní se váže na tento zdroj.
Objekt relace
{
"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"
} | Stav | Význam |
|---|---|
created | Řádek relace existuje; nikdo se ještě nepřipojil. |
open | Uživatel v terénu se připojil; relace je živá. |
recording | Probíhá nahrávání (volitelné, spouští operátor). |
closed | Relace ukončena. Hlava řetězce ukotvena u TSA; reporty k dispozici. |
expired | Naplánovaná relace, ke které se nikdo nepřipojil v rámci TTL. |
Vytvoření relace
POST /api/v1/public/sessions — Oprávnění 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"
}' Vrací nově vytvořený objekt relace (HTTP 201).
Pole těla
| Pole | Typ | Povinné | Poznámky |
|---|---|---|---|
notes | string | ne | Viditelné pro operátora. Zobrazuje se v pozvánkových e-mailech. |
scheduled_for | ISO 8601 | ne | Budoucí datum spustí připomínkové e-maily 24 h + 1 h předem. Vynechte pro "začít nyní". |
locale | string | ne | Jeden ze 14 podporovaných jazyků. Určuje jazyk SPA + PDF reportu. Výchozí je preference organizace. |
campaign | UUID | ne | Volitelný FK na kampaň pro dávkové reportování. |
Výpis relací
GET /api/v1/public/sessions — Oprávnění sessions:read
curl https://app.nexbasira.com/api/v1/public/sessions?limit=25 \
-H "Authorization: Bearer nb_sec_..." Stránkováno kurzorem. Předejte cursor z předchozí odpovědi next_cursor pro přechod na další stránku.
{
"data": [{ /* Session, Session, ... */ }],
"has_more": true,
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAy..."
} Načtení relace
GET /api/v1/public/sessions/{session_id} — Oprávnění sessions:read
Ukončení relace
POST /api/v1/public/sessions/{session_id}/end — Oprávnění sessions:write
Uzavře relaci, spustí ukotvení hlavy řetězce u všech nakonfigurovaných TSA a zahájí následné zpracování nahrávky, pokud nahrávání běželo. Idempotentní — volání na již uzavřenou relaci vrací uzavřený objekt relace bez opětovného ukotvení.
Vygenerování pozvánky pro uživatele v terénu
POST /api/v1/public/sessions/{session_id}/participants — Oprávnění 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"
} Hodnoty join_url a otp_code se v odpovědi zobrazí přesně jednou. Tokeny jsou vázány na IP/UA, jednorázové a časově omezené.
Dvoufaktorové připojení (OTP)
Když poskytnete alespoň jednu z hodnot recipient_email nebo recipient_phone, platforma automaticky vygeneruje 6místné číselné OTP a odešle ho na odpovídající kanál(y) v samostatné zprávě oddělené od join URL — vícevrstvá obrana, aby přeposlaný e-mail nebo SMS neodhalily oba faktory najednou. Prostý kód je také vrácen v odpovědi ( otp_code), abyste ho mohli v případě selhání doručení znovu sdílet ručně.
Na straně terénu SPA při prvním uplatnění zobrazí výzvu k zadání OTP. Kód odešlete přes hlavičku X-Join-OTP při opakovaném volání GET /v1/sessions/{id}/join/{token} — hlavička (nikoli URL) drží kód mimo historii prohlížeče a přístupové logy.
Pravidla OTP:
- 6místné číselné, v klidu hashované pomocí SHA-256 + pepper.
- 10minutové TTL od vydání.
- 5 chybných pokusů uzamkne pozvánku (HTTP 423) — operátor ji musí vydat znovu.
- Ověřuje se jednou při prvním uplatnění; opakované uplatnění ze stejné dvojice IP / UA přeskočí kontrolu (token je již vázán).
- Osobní předání URL (bez
recipient_email+ bezrecipient_phone) přeskočí generování OTP — samotná URL je autentizačním faktorem. Používejte pouze pro osobní předání.
Kódy odpovědí u GET /v1/sessions/{id}/join/{token}:
| Stav | Tělo | Význam |
|---|---|---|
| 200 | {field_session_token, livekit, ...} | OTP prošlo (nebo není vyžadováno); relace v terénu je živá. |
| 401 | {detail:"otp_required", channels:[...], channel_hint_email, channel_hint_phone} | SPA by mělo vykreslit formulář pro zadání OTP. |
| 401 | {detail:"otp_invalid", attempts_remaining} | Chybný kód; zobrazte zbývající pokusy. |
| 401 | {detail:"otp_expired"} | 10minutové okno vypršelo; operátor musí vydat znovu. |
| 423 | {detail:"otp_locked"} | 5 chybných pokusů; pozvánka je neplatná až do opětovného vydání. |
Časté chyby
| Stav | Kód | Kdy |
|---|---|---|
| 402 | billing.subscription_past_due | Předplatné organizace u Stripe je po splatnosti. |
| 402 | billing.free_plan_minutes_exhausted | Úroveň Free / Pilot vyčerpala svých 5 inspekcí. |
| 403 | permission_denied | Přihlašovacím údajům chybí sessions:write Oprávnění. |
| 409 | session.already_ended | Pokus o ukončení relace, která je již uzavřená (vzácné — `end` je normálně idempotentní). |
| 429 | rate_limited | Dosažen limit 60 rpm na přihlašovací údaje nebo 600 rpm na organizaci. Viz X-RateLimit-Reset hlavičku. |
Viz Chyby + omezení počtu požadavků pro úplnou strukturu obálky chyby a pokyny k opakování.