Skip to content

Submit a capture-session selfie (liveness poll or upload)

POST/v1/vision/selfie-submit

Authenticates with client credentials — no bearer token required.

Forwards the request verbatim to identity-kyc's internal `redeem-selfie` endpoint and maps its response back to the widget faithfully — this is a thin passthrough, not a second copy of the business logic. No OAuth bearer token: `capture_session_token` in the body is the entire authorization, verified downstream when this handler calls identity-kyc. A request either polls a pending vendor liveness session (no `selfie_image_base64`) or uploads a frame directly (`selfie_image_base64`, optionally with `liveness_degraded: true` after a prior 503) — see identity-kyc's own `RedeemSelfieCapture.ts` for the full two-path dispatch. `200` reports `provenance: 'controlled'` (a vendor-verified live frame) or `'submitted'` (an uploaded frame, never vendor-verified), or `provenance: null, routed: 'review'` when the liveness retry budget is exhausted without a passing attempt — the case still proceeds, just without a controlled selfie. `409 liveness_retake` (with `attempts_remaining`) means the widget should poll again; it is an ordinary retry signal, not a problem+json body. `503` (`code: liveness_unavailable`) means the vendor check is down — the widget's own fallback is to capture locally and resubmit with `selfie_image_base64` and `liveness_degraded: true`. Served by the vision host, not the primary API host (see the second `servers` entry), same as documentScan — temporary pending the unified API edge (ADR-0043). Rate-limited per-source-IP (RIGID-591 pattern, fixed 60s window); a 429 carries a `Retry-After` header.

Request body

capture_session_tokenstringrequired
selfie_image_base64string
liveness_degradedboolean

Example

curl -X POST https://vision.dev.rigid.fi/v1/vision/selfie-submit \
  -H "Authorization: Bearer $RIGID_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "capture_session_token": "string"
}'

Responses

200

The selfie was redeemed (`provenance: controlled | submitted`), or the liveness retry budget is exhausted (`provenance: null, routed: 'review'`).

One of

Option 1

case_idstringrequired
provenance"controlled" | "submitted"required

Option 2

case_idstringrequired
provenanceunknownrequired
routed"review"required
400

Validation error

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
404

Capture session not found or expired

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
409

A pending liveness check has not yet produced a passing verdict — poll again.

code"liveness_retake"required
attempts_remainingintegerrequired
410

The capture session scan budget is exhausted (`code: scan_budget_exhausted`) — the stored image will still be reviewed, so the widget should land on its done/review terminal rather than treating this like an expired session

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
429

Too many selfie submits from this address — retry shortly

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
500

Internal server error

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
503

The liveness check is temporarily unavailable (`code: liveness_unavailable`) — the widget should fall back to its own capture and resubmit with `selfie_image_base64` and `liveness_degraded: true`

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring