Appearance
Webhooks
Webhooks are an important part of the EyeDp platform. They tell your systems when something happens on a case, so you don't have to keep asking. There are two kinds:
- Check webhooks tell you when a check has completed. Checks are performed asynchronously in the background, so webhooks are the only way of getting notified when they're completed.
- Case change webhooks tell you when a case is created, its details change, or it's deleted, so you can keep your own copy of the case up to date. See Case change webhooks.
Events
These are all the events webhooks can be setup for.
| Event name | Description |
|---|---|
| tamper-detection/completed | Tamper detection check has completed |
| content-validation/completed | Content validation check has completed |
| aml/completed | Sent when a background ongoing monitoring aml check has found matches. Does not get sent for AML checks completed via the API or Portal. Includes the check id which can be used to get the list of matches from the AML checks endpoint. |
| kyc/completed | KYC check has completed |
| financial-vulnerability/completed | Financial vulnerability check has completed |
| bank-account-verification/completed | Bank account verification check has completed |
| automated-doc-verification/completed | Automated document verification check has completed |
| document-comparison/completed | Document Comparison check has completed |
| tamper-lite/completed | Tamper Lite check has completed |
| tamper-detection/skipped | Tamper detection was skipped on a document because Tamper Lite raised a risk on it. Only sent if you've chosen to skip Tamper Detection in that case. Sent once per document file. |
| case-details/changed | A case was created, its details changed, or it was deleted. Unlike the events above, this isn't about a check. See Case change webhooks. |
Register with the names in the table. In the payload, eventType is the part before the slash and action is the part after it. For example, you register tamper-detection/completed and receive "eventType": "tamper-detection" and "action": "completed", or register case-details/changed and receive "eventType": "case-details" and "action": "changed".
Example check webhook event
This is what a check webhook event looks like.
json
{
"caseId": 374,
"eventType": "tamper-detection",
"action": "completed",
"checkId": 123,
"timestamp": "2025-08-26T10:04:59.513Z"
}| Field | Description |
|---|---|
caseId | The case the event is for. |
eventType | The check, e.g. tamper-detection. |
action | What happened to the check: completed or skipped. |
checkId | The check's result, for the checks endpoints. null when the check was skipped, as a skipped check has no result. Check action before fetching the result, especially if several events are sent to the same URL. |
timestamp | When the event was sent. |
A skipped event identifies the case but not the document. Use case progress to see which document files Tamper detection was skipped on.
json
{
"caseId": 374,
"eventType": "tamper-detection",
"action": "skipped",
"checkId": null,
"timestamp": "2025-08-26T10:04:59.513Z"
}Authentication
Webhooks are sent with a custom header key value of your choosing. Use these to authenticate events coming into your endpoint.
E.g. x-my-auth: 758375
Create webhooks
Configures a new webhook.
| Endpoint | /api/webhooks |
|---|---|
| Method | POST |
| Content type | application/json |
Request
json
{
"url": "https://webhook.site/123",
"eventType": "financial-vulnerability/completed",
"authHeaderKey": "testheader",
"authHeaderValue": "123"
}IMPORTANT
Only one url can be configured per event type. Setting an event type will override the previous one.
Get webhooks
Returns all of webhooks configured for your company.
| Endpoint | /api/webhooks |
|---|---|
| Method | GET |
| Content type | application/json |
json
[
{
"createTs": "2025-08-26T12:44:56.113",
"url": "https://webhook.site/1234",
"eventType": "financial-vulnerability/completed",
"authHeaderKey": "testheader",
"authHeaderValue": "123"
},
{
"createTs": "2025-08-26T12:44:15.343",
"url": "https://webhook.site/123",
"eventType": "content-validation/completed",
"authHeaderKey": "testheader",
"authHeaderValue": "123"
}
]Case change webhooks
Subscribe to case-details/changed to hear about every change to your cases: when one is created, when its details are added, updated or removed, and when it's deleted. Use them to keep your own records in line with ours.
A case change webhook tells you what changed, never the values. To get the latest details, fetch the case with Get case. This keeps personal data out of webhooks, and means you always work from the current case even if webhooks arrive out of order.
Example case change webhook event
This is what a case change webhook event looks like.
json
{
"notificationId": "6f1c2a3b-4d5e-4f60-8a9b-0c1d2e3f4a5b",
"eventType": "case-details",
"action": "changed",
"caseId": 374,
"changeType": "detailsChanged",
"source": "portal",
"changes": [
{ "field": "addressLine4", "change": "updated" },
{ "field": "addressPostcode", "change": "updated" },
{ "field": "emailAddresses", "change": "added" }
],
"timestamp": "2026-10-15T10:04:59.513Z"
}Fields
| Field | Description |
|---|---|
| notificationId | Identifies this notification. The same on every delivery attempt, and also sent as the webhook-id header. |
| eventType | Always case-details. |
| action | Always changed. What happened to the case is in changeType. |
| caseId | The case that changed. |
| changeType | What happened to the case. See Change types. |
| source | What made the change: portal (someone using the EyeDp portal), publicApi (a request to the API) or documentExtraction (details read from documents uploaded to the case). |
| changes | Each field of the case that changed. Empty when the case was deleted. See Changes. |
| timestamp | When the change was made, in UTC. |
We may add new values to changeType, source and change. Ignore any you don't recognise.
Change types
| changeType | Meaning |
|---|---|
| caseCreated | The case was created. changes lists the fields it was created with, each as added. |
| detailsChanged | Fields of an existing case were added, updated or removed. |
| caseDeleted | The case was deleted. changes is empty. Get case then returns 404 for it, including when an earlier webhook for the case arrives after this one. |
Changes
Each entry in changes names one field, exactly as it appears in the Get case response, so you can read its new value from there:
| Field | Description |
|---|---|
| field | Which field changed. See the list below. |
| change | added (it had no value and now has one), updated (its value changed) or removed (it had a value and now has none). |
These are the fields a change can be reported for:
| Group | Fields |
|---|---|
| Case | urn |
| Person | title, givenNames, surname, fullname, dobYear, dobMonth, dobDay, gender, genderId, countryOfCitizenship |
| Address | addressLine1, addressLine2, addressLine3, addressLine4, addressLine5, addressLine6, addressLine7, addressPostcode, fullAddress, addressCountry, addressCountryCode2 |
| Contact | emailAddresses, phoneNumbers |
Some values appear in more than one field of the response, so one change can be reported as two: a new gender changes both gender and genderId, and a new address country changes both addressCountry and addressCountryCode2. emailAddresses and phoneNumbers are each reported as a whole list: changing one email address reports emailAddresses as updated.
When they're sent
- Only when something changes. Saving a case without changing any of its details doesn't send one.
- Only while you're subscribed. Changes made before you subscribe to
case-details/changedaren't sent later, so fetch any existing cases you need with Get case first. - Not for documents. Uploading or removing documents doesn't send one.
- Only for fields the Get case response returns. Changes to anything else about a case, such as an entity case's name or registration number, don't send one. For an entity case, only
urn,emailAddressesandphoneNumbersare reported for now, since Get case doesn't return an entity's other details. - Cases created from documents. When a case is created by uploading documents, it starts with only a temporary generated
urn. You'll receive acaseCreatedwebhook straight away, withsourceset topublicApiorportaldepending on where the documents were uploaded, listing justurnasadded. Once the documents have been read, the case's details are filled in and it's given a newurn, and you'll receive adetailsChangedwebhook withsourceset todocumentExtraction, listingurnasupdatedalong with whatever was read. Don't rely on the firsturn: match oncaseIdinstead. For an entity case, if no name could be read from the documents, theurnisn't replaced and nodetailsChangedwebhook is sent then. A later edit sends one as usual if it changes theurnor contact details.
Delivery
Your endpoint should respond with any 2xx status within 15 seconds. If it doesn't:
- These are tried again:
5xxresponses,408,429, timeouts and connections that fail. Retries happen after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, so 6 attempts in all over about 8½ hours. - These aren't: any other
4xxresponse, and redirects (3xx), which aren't followed. Make sure the URL you register is the one that receives the webhook.
Each attempt goes to the URL registered at that moment, so if you create a new webhook for case-details/changed, which replaces the old one, retries go to the new URL.
Because of retries, the same notification can occasionally arrive more than once. Use the webhook-id header, or notificationId, to ignore one you've already processed.
Webhooks can also arrive in a different order from the changes they describe. Rather than applying them in order, fetch the latest case each time.
IMPORTANT
The URL must be a public http or https address, and the auth header's name and value must be plain ASCII text. The auth header can't be one HTTP uses to route or frame the request: Host, Content-Length, Content-Type, Transfer-Encoding, Connection, Keep-Alive, Upgrade, TE, Trailer, Expect, or any header starting with Proxy-. Authorization and custom headers such as x-my-auth are fine. These rules aren't checked when you create the webhook. If one is broken, case change webhooks can't be sent to it and aren't retried.

