Skip to content

Verify API

Base URL: https://hakim-verify-api.vercel.app

Key Where it goes Allows
Publishable pk_… in the page, in the box’s endpoint starting sessions and polling results for your tenant
Secret sk_… your server only reading and cancelling your tenant’s results
Method and path Caller Purpose
POST /v1/<pk>/new the box start a session → { id, deepLink, expiresAt, … }
GET /v1/<pk>/session/:id the box hand-off details again; 410 once expired
GET /v1/<pk>/result/:id the box current state
POST /v1/<pk>/close/:id wallet the holder dismissed the request
POST /v1/<pk>/dcapi/:id the box Digital Credentials API response
GET /v1/<pk>/request/:id wallet the signed request
POST /v1/<pk>/response/:id wallet the presentation
GET /v1/results/:id your server, Authorization: Bearer sk_… the outcome
DELETE /v1/results/:id your server, Authorization: Bearer sk_… cancel a session

Page-facing routes answer CORS preflight for the origins on your tenant’s allowed list.

Configured per tenant: the name the wallet shows, the request (document and fields), the trusted issuers, allowed origins, the request validity window (ten minutes by default), the wallet hand-off settings, and optionally your own reader certificate. Results are stored per tenant; a secret key only reads its own.

{ "state": "verified", "verified": true, "docType": "org.iso.23220.photoid.1", "trustedChain": true,
"claims": { "family_name": "…", "portrait": "data:image/jpeg;base64,…" }, "namespaces": { "…": {} } }
{ "state": "failed", "verified": false, "error": "…" }
{ "state": "waiting" } // also: cancelled, expired
  • An expired session can never be approved (410); unknown ids read as expired.
  • A second submission returns the first outcome.
  • A late close never overrides a result.

Every state and error value is listed in Errors and states.