Webhooks deliver verification status changes to your endpoint in near real time. Register a callback URL once, and Sentinel POSTs a small JSON payload whenever a customer's status changes. This is the recommended way to receive outcomes.
Register a callback URL
From your backend, register where webhooks should be delivered and a secret used to verify them.
http
POST https://api.sentinel.example.com/clients/setWebhook/clientAuth
Field
Type
Description
clientUuidrequired
string
Your client identifier.
clientSecretrequired
string
Your client secret. Server-side only.
callbackUrlrequired
string
Where Sentinel POSTs webhooks. Must use HTTPS.
callbackPassphraserequired
string
A shared secret, minimum 6 characters, used to verify incoming webhooks.
Sentinel sends a POST with a JSON body to your callback URL.
Field
Type
Description
id
number
Internal customer id.
uuid
string
Customer UUID. Safe to use as your external key.
email
string
Email captured during the journey.
phone
string
Phone number captured during the journey.
newStatus
number
The customer status code. See the table below.
updatedAt
string (ISO)
Timestamp of the status change.
event
string
The event type. See events below.
expiryWarningFor
string[]
Documents nearing expiry. Populated only on expiry_warning. Values are snake_case here (passport, emirates_id, egypt_national_id), unlike the camelCase document values used elsewhere.
passphrase
string
The callbackPassphrase you registered. Use it to verify the request, as described below.
The default event. Sent whenever a customer status changes.
customer_created
The customer finishes the flow and a customer record is created. Opt in to receive it.
expiry_warning
A document is approaching expiry. Carries expiryWarningFor.
The default subscription fires on status change. If you also want a signal at the moment a customer record is created, when the customer finishes the flow, ask to enable the customer_created event.
Verify every webhook
Before trusting a payload, confirm it came from Sentinel by comparing the passphrase in the body to the callbackPassphrase you registered. Reject the request if they do not match.
javascript
app.post('/webhooks/sentinel', (req, res) => {
if (req.body.passphrase !== process.env.SENTINEL_CALLBACK_PASSPHRASE) {
return res.sendStatus(401)
}
// Trusted. Act on req.body.newStatus and req.body.uuid.
res.sendStatus(200)
})
Handle the secret with care
Serve your callback over HTTPS so the payload is never sent in the clear. Do not log the passphrase, keep it in server-side configuration, and rotate it periodically. Use the uuid as your key, and treat id as internal.
Status codes
newStatus is a numeric code. The full set is below. Codes marked reserved exist but are not currently emitted, so handle any unrecognized value defensively.
Code
Status
Meaning
1
Inactivereserved
Not currently emitted.
2
Draft
Re-verification required. Triggered by document expiry or set from the dashboard, with a reason shown to the customer.
3
More datareserved
Not currently emitted.
4
Expiredreserved
Not currently emitted.
5
Pending
Submitted; verifying and screening.
6
Accepted
Passed all checks.
7
Rejected
Did not pass.
8
Enhancedreserved
Not currently emitted.
9
Conflict
Held for review; submitted details do not reconcile.
10
Duplicate
Held for review; matches an existing record.
Accepted and Rejected are outcomes, but not necessarily permanent: an operator can change a status from the dashboard. Conflict and Duplicate are held for review and resolve to Accepted or Rejected. See Core concepts for the lifecycle.
Delivery and retries
Delivery is retried up to 3 times with exponential backoff. If every attempt fails, the webhook is dropped, so pair webhooks with result retrieval for critical workflows. Respond with a 2xx status quickly, and do any heavy processing asynchronously.