Verifications
A verification is the unit of work in VerifyAI. Every time you call
POST /v1/verify, we run the photo through a policy, write a row in
your account, and return a verification object.
{
"id": "ver_8x92m4k9",
"status": "success",
"is_compliant": false,
"confidence": 0.94,
"policy": "scooter_parking",
"category": "unsafe",
"violation_reasons": ["blocking_sidewalk", "kickstand_up"],
"feedback": "Please deploy the kickstand and move away from the walkway.",
"image_url": "https://...signed-url..."
}Lifecycle
- Request received. The API validates your key, ensures the subscription is active, and reserves a usage unit.
- Image stored. The raw image is written to per-customer object storage. The dashboard renders signed URLs that expire after a few minutes.
- Policy evaluated. Depending on the policy, we either call a
cloud VLM (OpenAI, Anthropic, or Gemini) or run on-device ML — see
evaluation_sourceon the response. - Result written. A row in
verify_ai_verificationscaptures the compliance decision, raw model output, token usage, and timings. - Response sent. You get the structured object back, plus an
X-Request-Idheader for traceability.
The whole loop typically completes in 800–1,500 ms including image upload.
Key fields
is_compliant
Top-level pass/fail. Use this for branching logic ("end the ride",
"prompt for retake"). Equivalent to the boolean isCompliant on a
verification's resolved category.
category
The outcome bucket the model placed the photo into. Built-in policies ship with these defaults:
| Category | Compliant | Use case |
| ------------- | --------- | ------------------------------------------------------- |
| compliant | yes | All criteria pass. |
| improvable | no | Minor issues; consider retake but not blocking. |
| unsafe | no | Hard fail — block the action, ask for retake. |
| lacks_info | no | Photo doesn't show enough to decide — ask for retake. |
Custom policies (like Forest's e-bike parking flow) can override these labels — see Concepts: Policies.
violation_reasons
Stable, machine-readable IDs of the failed criteria. Useful for
analytics (how often does each failure mode happen?) and for branching
inside your app (if (reasons.includes("blocking_emergency_exit"))…).
feedback
A user-facing sentence written by the model. Safe to show end users verbatim — the SDK scanners do this by default. The tone matches the policy's configuration; for example, Forest's policy is direct and action-oriented.
confidence
Model self-confidence in the range 0..1. We don't recommend gating
business logic on this field alone — the category decision already
accounts for severity weighting across criteria. Confidence is most
useful for monitoring (e.g., flagging low-confidence calls for human
review).
metadata
Whatever you sent in the request, persisted alongside the verification. Common patterns:
{
"user_id": "usr_…",
"vehicle_id": "veh_…",
"trip_id": "trip_…",
"gps": { "lat": 51.5072, "lng": -0.1276 }
}Metadata is searchable in the dashboard and exported with the audit
log. Don't put PII you don't actually need — user_id references are
typically enough.
evaluation_source
Either cloud_vlm (server-side VLM) or on_device (a result that the
SDK computed locally and submitted as a confirmation). On-device runs
return faster and cost less; we use them automatically for policies
with an on-device model bundle attached.
Storage and retention
- Images are retained for 30 days by default. Enterprise contracts can extend retention or pin storage to a specific region.
- Metadata and decisions are retained as long as your account is active. Export them via the API or dashboard at any time.
- Image URLs in API responses are signed and expire — fetch them
fresh from
GET /v1/verifications/:idwhen you need a fresh URL.
What's next
- Policies — how categories and criteria combine into a decision.
- Verify endpoint — the full request / response schema.
- Webhooks (coming soon) — push verification events to your own systems instead of polling.