Skip to main content
POST
Create a verification

Authorizations

Authorization
string
header
required

Secret API key, created in the dashboard under Settings → API. Send it as Authorization: Bearer rk_secret_… from your server only. Publishable keys (pk_live_…) are for the native SDKs and reach the capture endpoints alone. An unknown key returns 401.

Body

application/json

Send steps for guided photos, or max_captures for N anonymous photos (default 1) — never both. Everything else is optional.

Body for POST /v1/verifications. All fields optional — sensible defaults: max_captures: 1, expires_in_seconds: 3600, signals_required: ["screen", "ai"]. Capture quantity comes as EITHER max_captures (N anonymous captures) OR steps (guided slots with key/description/min/max) — never both. context is what the analysis pipeline cross-references against the capture; metadata is opaque pass-through echoed back on every webhook event.

max_captures
integer

How many anonymous photos to ask for. Use this or steps, never both. Default 1.

Required range: 1 <= x <= 20
steps
object[]

Guided steps in order: photos, text questions, uploads, choices, addresses. Use this or max_captures.

Minimum array length: 1
expires_in_seconds
integer
default:3600

How long the capture link stays open, in seconds. Default 3600 (one hour), max 86400.

Required range: 60 <= x <= 86400
signals_required
enum<string>[]

Checks to run on each photo: screen (photo of a screen), ai (AI-generated), reverse (already online), context (matches context). Default ["screen", "ai"].

Minimum array length: 1
Available options:
screen,
ai,
reverse,
context
seal
boolean
default:true

Stamp the delivered photos with a C2PA seal. Default true.

mode
enum<string>

verification (photo taken live, default) or audit (a file that already exists, uploaded through the API).

Available options:
verification,
audit
context
object

What the photo is supposed to show, for the context check: kind names the thing, summary describes it in one line.

webhook_url
string<uri>

HTTPS URL that receives verification.created and verification.completed.

notify_email
string<email> | null

Email that receives the result. null opts this verification out; absent uses your account default.

Maximum string length: 254
notify_subject_template
string | null

Subject of the result email. {variable} placeholders allowed.

Minimum string length: 1
notify_body_template
string | null

Body of the result email. {variable} placeholders allowed.

Minimum string length: 1
completion_message
string | null

Full plain-text message shown after submitting content. HTML, markdown and variables are not interpreted. Omit on create or send null on PATCH to use the default.

Required string length: 1 - 2000
metadata
object

Your own key/value strings, returned with every result and webhook. Example: { "claim_id": "CLM-9912" }.

requires_location
boolean

Require a GPS fix on the first photo without comparing it to an address.

expected_location
string

Street address the photo must be taken at. Turns on location_match.

Required string length: 1 - 300
expected_object
string

What must appear in the photo, e.g. "car". Turns on object_match.

Required string length: 1 - 200
condition_aspects
string[]

One to six aspects to score from 0 to 10, e.g. ["paint", "tires"]. Turns on condition.

Required array length: 1 - 6 elements
Required string length: 1 - 40
expected_info
object

Structured alternative to expected_location, expected_object and condition_aspects. Send one form or the other.

brand_slug
string

Brand profile shown on the capture page. Absent = your default brand.

Required string length: 2 - 40
Pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$

Response

Verification minted. Returns the canonical wire shape including the capture_url the tenant sends to the end-user.

A verification as your API key sees it. verdict appears once analysis finished; object_match, location_match and condition appear when you asked for them and the check ran. Your metadata is not echoed back: keep the id.

id
string
required
Pattern: ^vfy_[0-9A-HJKMNP-TV-Z]{26}$
status
enum<string>
required

Lifecycle state. pending → first capture flips to partially_captured → analysis sets the verdict and transitions to completed. Terminal: completed, expired, failed. abandoned is a side-branch off pending/partially_captured, reported by the capture screen via POST /v1/verifications/:token/progress when the end user leaves before finishing — NOT terminal: a later capture resurrects the row to partially_captured like any other.

Available options:
pending,
partially_captured,
completed,
expired,
failed,
abandoned
capture_url
string<uri>
required
created_at
string<date-time>
required
expires_at
string<date-time>
required
captures_count
integer
required
Required range: x >= 0
verdict
object

Verdict of a live capture. Branch on rial; signals says why when it is false.

location
object

Where the photo was taken, from the device. Absent for uploaded files and when the device reported no fix.

location_match
object

Whether the photo was taken at expected_location. verified within GPS tolerance; no_match somewhere else; ungeocoded when the address or the fix could not be resolved; rejected when the device reported a mock location.

object_match
object

Object-check result. Present when an object check was requested globally or on an image step. With step-only configuration the status is the worst step result and expected_object is omitted. Independent of the fraud verdict.

object_matches
object

Object-check results keyed by image step. Missing capture verdicts yield inconclusive; otherwise each value is the worst context result for the step, ignoring not_applicable when live evidence exists.

condition
object

Condition assessment. Present only when the verification was created with condition_aspects — the free-form tenant-defined aspect names (any language, any domain). score is the one-decimal average of aspect scores; label buckets it (>=7.5 good, >=5 fair, else poor). Independent of the fraud verdict.

video_analysis
object

Screen-detection analysis of a video-step clip, sampled at one frame per second. Written asynchronously after capture — poll or use webhooks; absent until the worker has run.

ocr_primary
string
answers
object
record_seal
object

Integrity seal over the verification record including answers. Present only when answers exist and sealing is on (seal !== false). The hash proves the stored answers have not changed — it does NOT claim they are true or sensor-attested; answers_provenance carries that distinction explicitly.