# Webhook

### Overview

The Webhook (aka: Global Webhook) lets you receive the result of every onboarding session straight to an endpoint of your choice, no matter how that session was started.

Onboarding sessions include "[Enrollment Flow](/docs/kyc/uqudo-sdk/integration/android/enrolment-flow.md)", "[NFC / Reading Flow](/docs/kyc/uqudo-sdk/integration/android/nfc-reading-flow.md)", and "[Lookup Flow](/docs/kyc/uqudo-sdk/integration/android/lookup-flow.md)".

Whether your users go through a Hosted KYC flow, your own mobile app using the Uqudo SDK, or any other integration method, the result is always delivered to the same place.

<figure><img src="/files/Qarm2114KkmsBO6FGvdI" alt=""><figcaption></figcaption></figure>

***

### When should I use it?

<table><thead><tr><th width="500.4000244140625">Situation</th><th>Use Global Webhook</th></tr></thead><tbody><tr><td>You use the <strong>Uqudo SDK</strong> directly (not Hosted KYC) and need to receive onboarding results server-side</td><td>✅ Yes</td></tr><tr><td>You have <strong>multiple Hosted KYC configurations</strong> and want all results going to one endpoint instead of repeating the same webhook URL in every config</td><td>✅ Yes</td></tr><tr><td>You want a <strong>single, centralised receiver</strong> for all onboarding activity across your account</td><td>✅ Yes</td></tr><tr><td>You only have one Hosted KYC configuration and already have a webhook configured there</td><td>⚠️ Optional, see Using both</td></tr></tbody></table>

***

### How it works

Once configured, whenever an onboarding session completes for your account, Uqudo sends an HTTP `POST` request to your endpoint with the session result.

The request body is a JSON object:

```json
{
  "jwsResult": "<signed JWT string>"
}
```

The [`jwsResult`](/docs/kyc/uqudo-sdk/sdk-result.md) is a signed JWT containing the full onboarding data. You can verify its signature using Uqudo's public key and then decode the payload to access the [result](/docs/kyc/uqudo-sdk/sdk-result.md).

***

### Difference from the Hosted KYC webhook

You may already be familiar with the webhook that can be set per Hosted KYC configuration. Here is how they compare:

|                          | **Hosted KYC Webhook**                | **Global Webhook**                                 |
| ------------------------ | ------------------------------------- | -------------------------------------------------- |
| Scope                    | One specific Hosted KYC configuration | All onboarding sessions across your entire account |
| Works with the Uqudo SDK | ❌ No                                  | ✅ Yes                                              |
| Configuration            | Per Hosted KYC config                 | Once per account                                   |

> **In short:** the Hosted KYC webhook is tied to a specific flow configuration. The Global Webhook is account-wide and method-agnostic.

***

### Using both (Global and Hosted KYC webhook)

You can run both at the same time. They are completely independent, one does not replace or affect the other.

> ⚠️ **Important:** if you configure the same endpoint URL in both your Global Webhook and a Hosted KYC configuration, **your endpoint will receive two identical notifications** for every session that goes through that Hosted KYC flow. This is by design.

If you only want one delivery per session, either:

* Remove the webhook from the individual Hosted KYC configuration and rely solely on the Global Webhook, or
* Keep the per-config webhook and do not set a Global Webhook.

***

### Configuring the Global Webhook

You can manage the Global Webhook from the Customer Portal under **Development → Webhook**.

You can only have **one** Global Webhook per account. Saving a new configuration always replaces the previous one.

#### Security options

<table><thead><tr><th width="211.60003662109375">Security Type</th><th>When to use</th></tr></thead><tbody><tr><td><code>NONE</code></td><td>No authentication: your endpoint is publicly accessible or protected by network controls</td></tr><tr><td><code>BASIC_AUTHENTICATION</code></td><td>HTTP Basic Auth: provide a username and password that Uqudo will include in every request</td></tr><tr><td><code>CUSTOM_HEADERS</code></td><td>Inject one or more custom HTTP headers (e.g. <code>X-Api-Key</code>): useful for API gateway tokens</td></tr></tbody></table>

#### Configuration fields

<table><thead><tr><th width="164.199951171875">Field</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><code>url</code></td><td>✅ Always</td><td>The HTTPS endpoint that will receive the onboarding result</td></tr><tr><td><code>securityType</code></td><td>✅ Always</td><td>One of <code>NONE</code>, <code>BASIC_AUTHENTICATION</code>, <code>CUSTOM_HEADERS</code></td></tr><tr><td><code>userId</code></td><td>When <code>securityType</code> is <code>BASIC_AUTHENTICATION</code></td><td>Basic Auth username</td></tr><tr><td><code>password</code></td><td>When <code>securityType</code> is <code>BASIC_AUTHENTICATION</code></td><td>Basic Auth password</td></tr><tr><td><code>customHeaders</code></td><td>When <code>securityType</code> is <code>CUSTOM_HEADERS</code></td><td>List of headers (1–5), each with a <code>name</code> and <code>value</code></td></tr></tbody></table>

***

### Receiving and validating results

When your endpoint receives a request:

1. **Verify the signature** of the `jwsResult` JWT using Uqudo's public key to confirm the payload has not been tampered with.
2. **Decode the JWT payload** to access the onboarding result data (document scan, face verification, background check, etc.).
3. **Extract the session ID** from the `jti` claim if you need to correlate the result back to a session in your system.
4. **Return a `2xx` response** as quickly as possible. If your endpoint is slow or returns a non-2xx status, Uqudo will retry delivery automatically.

> Your endpoint should be **idempotent**, i.e. processing the same session ID twice should have no unintended side effects, in case a retry delivers the result more than once.

***

### Retry behaviour

If your webhook endpoint is temporarily unavailable or fails to respond, Hosted KYC includes a retry mechanism to help ensure delivery.

* We automatically retry sending the webhook **every 5 minutes**
* Retries continue for up to **2 hours** from the initial attempt

If the webhook is still not successfully delivered after this period, the message will be **dropped**.

***

### Deleting the Global Webhook

Removing the Global Webhook stops future deliveries immediately. Sessions that are already in flight at the time of deletion may still attempt delivery once before the change takes effect.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.uqudo.com/docs/kyc/readme/customer-portal/webhook.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
