Skip to main content
Webhooks notify your endpoint the moment a verification session reaches a terminal status. Configure a webhook once and you stop polling for results.

How it works

1

Configure

Add a webhook URL in the Partner Portal, or pass webhookUrl when creating a session.
2

Verify

A user completes (or fails) their verification session.
3

Deliver

Cr3dentials sends a POST to your URL when the session reaches a terminal status: COMPLETED, PARTIAL_COMPLETE, ERROR, CANCELLED, or TERMINATED.
4

Process

Your endpoint receives the payload and updates your application.

Create a webhook in the Partner Portal

1

Open Webhooks

Log into the Partner Portal and click Webhooks in the sidebar.
2

Create a webhook

Click Create Webhook and enter your endpoint URL (https://your-domain.com/webhook). It must be HTTPS.
3

Set authentication (optional)

Add a custom header key/value (for example X-API-Key: your-secret). Cr3dentials includes it on every delivery so you can validate the request server-side.
4

Tune delivery (optional)

Set the response timeout and retry attempts, then toggle the webhook Active.
You can create a webhook inactive and enable it later. Use the Test action in the portal to send a sample payload and confirm your endpoint responds.

Payload

Each delivery is a POST with this body:
{
  "sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "COMPLETED",
  "platformId": 1,
  "externalReferenceId": "user_abc123",
  "extractedData": {
    "accountHolder": "John Doe",
    "accountType": "checking"
  },
  "proofHash": "9f2c…",
  "completedAt": "2025-03-24T12:05:00.000Z",
  "metadata": {}
}
sessionId
string
The session this event is for.
status
string
Terminal status: COMPLETED, PARTIAL_COMPLETE, ERROR, CANCELLED, or TERMINATED.
platformId
number
Platform the session verified against.
externalReferenceId
string | null
Your reference ID from session creation, if you provided one.
extractedData
object | null
Verified account data, present when verification completed.
proofHash
string | null
Opaque reference to the cryptographic attestation (SHA-256). The raw attestation is never sent.
completedAt
string | null
ISO 8601 completion timestamp.
metadata
object | null
Non-sensitive session metadata. Internal fields are stripped before delivery.

Handle the webhook

// Node.js / Express
app.post('/webhook/cr3dentials', (req, res) => {
  // Validate the auth header you configured in the portal
  if (req.headers['x-api-key'] !== process.env.CR3D_WEBHOOK_SECRET) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Acknowledge immediately, process asynchronously
  res.status(200).json({ received: true });

  const { sessionId, status, extractedData } = req.body;
  setImmediate(() => updateVerification(sessionId, status, extractedData));
});

Requirements

Your endpoint must:
Respond with a 2xx status code.
Respond within the configured timeout (default 30 seconds).
Handle duplicate deliveries idempotently (key off sessionId).
Always validate the configured authentication header server-side before trusting a payload. Acknowledge fast and do heavy work asynchronously so you don’t hit the timeout.

Retries

Failed deliveries are retried automatically with exponential backoff, up to the retry count configured for the webhook (default 3). Review delivery history and failures under Webhooks → Logs in the portal.

Troubleshooting

Confirm the webhook is Active, the URL is reachable over HTTPS with a valid certificate, and your server returns a 2xx. Check the delivery logs in the portal.
Common causes: non-2xx responses, slow responses past the timeout, or TLS certificate problems. Inspect the logged status code and error for each attempt.
Make sure the header key and value in your endpoint exactly match what you configured in the portal.