LIVE · AUDIT-CHAINED · EU-RESIDENT
SYSTEM · 99.99% UPTIME
v 1.0 ↗ MADE IN EU

Evidence API

An Evidence row is one artefact captured during a session — a snapshot, a whiteboard, a video clip, a recording, or an uploaded document. Every row carries a sha256 + byte_size + mime so the integrity-verification chain can prove the bytes weren't tampered with between capture and audit.

The Evidence object

{
  "id": "ev-7f3a...",
  "session": "0c8f4d2e-1a3b-4c5d-9e7f-1234567890ab",
  "kind": "snapshot",
  "status": "ready",
  "mime": "image/jpeg",
  "byte_size": 184523,
  "sha256": "f9cc12fda76c30dcc9bee627baed6c9e8fe11b813313de70b1463f9f73e5e418",
  "captured_at": "2026-05-23T10:14:02.481Z",
  "created_at": "2026-05-23T10:14:02.917Z",
  "completed_at": "2026-05-23T10:14:03.211Z"
}

Kinds

KindCaptured byNotes
snapshotOperator or field-sideSingle still frame (JPEG). The most common kind.
whiteboardOperatorExcalidraw export — PNG + canonical JSON. See Whiteboards.
clipOperatorShort MP4 cut from the live session — used to capture motion the field user demonstrates.
recordingSystemFull session recording. Post-processed to libx264 medium / crf20 after the session ends.
documentOperatorFile attachment from the in-session chat (PDFs, photos, etc.). Foundation for PDF-for-signature.

Status

StatusMeaning
pendingRow created; bytes not yet in object storage.
uploadingMultipart upload in progress.
readyBytes are persisted; sha256 + byte_size are finalised. Only ready rows are downloadable.
failedCapture or upload aborted. completed_at is null.

List session evidence

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

curl "https://app.nexbasira.com/api/v1/public/sessions/0c8f.../evidence?kind=snapshot&limit=50" \
  -H "Authorization: Bearer nb_sec_..."

Query params

ParamTypeNotes
kindstringFilter — one of snapshot, whiteboard, clip, recording, document.
limitintMax 100. Defaults to 25.
cursoropaqueFrom the previous response's next_cursor.

Get a signed download URL

GET /api/v1/public/evidence/{evidence_id}/download — scope evidence:read

Returns a short-lived presigned URL the customer fetches the raw bytes from. The URL points directly at the object-storage backend (MinIO / S3 / GCS depending on your deployment) so downloads bypass our app servers — no bandwidth-egress charges from your end of the public API.

curl "https://app.nexbasira.com/api/v1/public/evidence/ev-7f3a.../download" \
  -H "Authorization: Bearer nb_sec_..."
{
  "url": "https://s3.eu-central-1.amazonaws.com/nb-prod-evidence/orgs/.../snapshot.jpg?X-Amz-Algorithm=...",
  "expires_in_seconds": 900,
  "sha256": "f9cc12fda76c30dcc9bee627baed6c9e8fe11b813313de70b1463f9f73e5e418",
  "byte_size": 184523,
  "mime": "image/jpeg",
  "kind": "snapshot"
}

Re-call when the URL expires — no rate-limit penalty for repeated mints. After downloading, hash the bytes with SHA-256 and compare to the returned sha256 to verify the file is intact end-to-end.

# integrity check — Python
import hashlib, requests
r = requests.get(presigned["url"]); r.raise_for_status()
assert hashlib.sha256(r.content).hexdigest() == presigned["sha256"]

Common errors

StatusCodeWhen
403permission_deniedCredential lacks evidence:read.
404not_foundEvidence row doesn't exist in the credential's org.
409evidence_not_readyDownload requested on a row whose status is not ready.
410retention_expiredOrg's retention policy has passed the row's age cutoff; bytes have been purged from object storage.

Notes

  • No POST/PATCH/DELETE. Evidence is captured client-side (operator + field SPA) during the session. The public API is read-only on this resource.
  • Retention. Each org configures a retention window (default 7 years for eIDAS-compliant deployments). After the window, object-storage lifecycle rules purge bytes; the row stays so the audit chain doesn't break, but /download returns 410.
  • Anchored in the audit chain. Every ready row contributes its sha256 to the per-session hash chain, which is anchored at the TSA on session end. The chain head + TSA receipt are reachable via the SPA-side audit-verify endpoint.