Session Webhooks
When you create a verification request from your backend, you can attach a callback that belongs to that verification run only. It is delivered in addition to every configured organization endpoint, and it is never added to the endpoint registry.
Use it when a single run needs its own destination — a per-tenant callback, a short-lived worker, a test harness — without permanently changing your organization's webhook configuration.
Installing one
Pass a webhook object to the SDK verification-request creation call:
curl -X POST "https://api.zyphe.com/sdk/flow/${ZYPHE_FLOW_ID}/vr/create?sandbox=true" \
-H "x-api-key: ${ZYPHE_SECRET_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"email": "applicant01@example.com",
"customData": { "customerReference": "C-123" },
"webhook": {
"url": "https://api.example.com/verifications/session-42",
"secret": "a-32-byte-or-longer-secret-you-generated",
"eventTypes": ["verification.dv.completed", "verification.dv.failed", "flow.completed"],
"payloadVersion": "V2"
}
}'
| Field | Required | Notes |
|---|---|---|
url | yes | HTTPS, up to 2048 characters. Re-validated against the public-address rules before every delivery. |
secret | yes | You generate it, minimum 32 characters. Zyphe signs with it and never returns it. |
eventTypes | no | Omit to receive every verification and flow event this run produces. |
payloadVersion | no | Defaults to V2. See Payload Versions. |
The response confirms what was installed:
{
"sessionId": "cbe0f5cd-6f38-4a2e-9c3f-0a2f9e2b7c14",
"sessionWebhook": {
"id": "8a1c0d33-59a2-4f6c-9c30-64e1c1a4f0f2",
"secretHint": "…cret",
"expiresAt": "2026-09-25T10:00:00Z"
}
}
Rules
- A Secret API key is required. A Publishable key may be embedded in a browser page, so it is not allowed to install a callback URL. Requests that carry
webhookwith a Publishable key are rejected. - The secret is yours. It is never minted or returned by Zyphe, which is what makes resuming a run idempotent: the same call with the same secret is safe to retry, and nothing has to be re-disclosed.
- Resuming replaces. Supplying
webhookagain while resuming the same run replaces the previous callback; omitting it leaves the existing one in place. - Lifetime is 30 days, fixed by the server. After
expiresAt, deliveries to it are skipped. - Scope is enforced at send time, not just when routing: a callback can only ever observe its own organization, flow, identity, and run.
- Not everything is subscribable.
transaction.alert.createdandkyc_passport.verification.updatedare rejected here — they belong to audiences a verification session does not define.
Verifying
Signature verification is identical to any other webhook, using the secret you supplied. See Webhook Signature.