Check a verification code
Phone methods only: a government_id recipient has no code to check (400 unsupported_method) — that verdict arrives from Persona on POST /webhooks/persona. Checks the code with the verification provider. On success the server records the verification and sets an HttpOnly session cookie scoped to this signing link (valid 2 hours); the cookie, not the response body, is what later authorizes signing actions, and a page refresh keeps it. A successful verification replaces any earlier session for this link — there is one active session — so a signer who verifies from a second browser ends the first browser session at that moment. Five wrong codes per sent code exhaust the attempt budget (verification_too_many_attempts) until a new code is sent. Requires the access code first when one is set.
View as MarkdownPath Parameters
Header Parameters
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/public/signing/string/verification/verify" \ -H "Content-Type: application/json" \ -d '{ "method": "sms", "code": "string" }'{ "verified": true, "expiresAt": "2019-08-24T14:15:22Z"}Live signing events (SSE)
A Server-Sent Events stream that tells the signer's open page their Government ID check has been decided, so it can re-read the session at once instead of polling. The token is the credential and the stream is routed by the recipient it resolves to. Frames carry no result, only a nudge: the session endpoint (GET /public/signing/{token}) remains the sole decision and the only place the verified-session cookie is set. The stream emits `event: ready` once on connect (re-read the session, an event may have been missed while disconnected), then `event: verification` with `{"status":"verified"|"failed"|"expired"}` when the check settles, plus `: ping` heartbeat comments every 25s. The server ends the stream after 15 minutes. Delivery is best-effort, so keep a slow fallback poll of the session. 404 when the link has no Government ID check to follow; 503 when the server has no event listener (poll instead).
Persona inquiry webhook (Government ID verification)
Receives Persona's inquiry events. Called by Persona only — there is no session, and the request is authenticated by the Persona-Signature header (t=<unix time>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">, one space-separated pair per secret while a secret is being rotated), checked against PERSONA_WEBHOOK_SECRET over the raw body before it is parsed. The event is only a signal. The inquiry it names is read back from Persona, and that answer — never the payload — decides. The inquiry must be held by exactly one verification row, with the same recipient as its reference id and the configured Inquiry Template. Only the approved decision verifies the recipient: declined and failed move it to failed, expired to expired, and completed, needs_review, or any status this service does not know changes nothing. A settled verification never moves again, so redeliveries and out-of-order events are harmless, and an event about an inquiry that has since been replaced matches no row. An event for a document that is no longer signable (completed, declined, voided, expired, or this recipient already signed or declined) is ignored. Events that are not for this service are acknowledged with 200 so Persona stops retrying them. Only a failure a retry could fix (503: Persona could not be read, 500) asks for redelivery.