> For the complete documentation index, see [llms.txt](https://developer.algbralabs.com/partner-banking/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.algbralabs.com/partner-banking/concepts/webhooks/webhook-guidelines.md).

# Webhook Guidelines

## Request Structure

Algbra platform will always send HTTP requests with `POST`method to your configured webhook handler URLs with the following Headers and Body payload.

### Headers

| Header Key      | Description                                                                    |
| --------------- | ------------------------------------------------------------------------------ |
| content-type    | Always set to \`application/json\`                                             |
| date            | A time to  stamp to verify if the clock drift is in acceptable range value     |
| x-alg-nonce     | A unique one-time value for each webhook trigger.                              |
| x-alg-signature | Base64 encoded digital signature to verify authenticity of the webhook trigger |

### Body

You will receive webhook triggers with the following JSON structure. The contents of `payload` field will vary based on the event triggered. Please refer to section [Supported Events](/partner-banking/concepts/webhooks/supported-events.md) in this document to learn more about details of each event type and payload structure.

```json
{
	"event": "<event-name>",
	"eventId": "<unique event id>",
	"version": "<version-of-the-event-payload>",
	"payload": {
		// detailed payload fields vary per event type
	}
}
```

## Processing Webhooks

When you get a webhook trigger, first you need to validate the authenticity of the request before you proceed to process actual data provided.

### Verifying Webhooks

In order to validate the authenticity and uniqueness of each webhook event, you need to follow steps described below.

{% stepper %}
{% step %}

### Validate Nonce

Ensure the nonce value has not been processed before, store the nonce for a configurable time (ie. 24 hours) to identify and prevent reply attacks.
{% endstep %}

{% step %}

### Validate Time Stamp

Verify the time stamp value by checking if it is in acceptable range (ie. ±5 minutes) to account for clock drift.
{% endstep %}

{% step %}

### Hash & Verify

Create a JSON message with the following structure, and hash with `SHA256`then verify using the public key shared with you and the signature from `x-alg-signature` header from the request.

{% hint style="warning" %}
Please make sure the field name casing and the order of the fields are exactly as explained below. Otherwise verification will fail.
{% endhint %}

```json
{
    "url": "<path of the webhook handler url>",
    "method": "POST",
    "headers": {
        "date": "<unique nonce from request headers>",
        "x-alg-nonce": "<date stamp from request headers>"
    },
    "body": "<raw request body>"
}
```

{% endstep %}
{% endstepper %}

### Responding to Webhooks

You need to make sure response headers and status code conforms the details explained below.

### Response Headers

| Header Key  | Header Value                                |
| ----------- | ------------------------------------------- |
| x-alg-nonce | Nonce value provided at the request headers |

### Response Body and Status Code

We don't expect partners to return any response data to webhook requests other than a successful HTTP status code `2xx` when a webhook handled correctly.

### Eventual Consistency

To ensure successful receipt of a webhook, duplicate webhooks must be handled idempotently. Always respond with the correct format, even for duplicate or retried webhooks, so we can confirm receipt. We use an at-least-once delivery strategy, which means you may receive the same webhook multiple times.

We may send the same event trigger one or more times to your URL configured. In order to handle subsequent triggers with the eventual consistency in mind, you can use `eventId` field from the webhook request to detect duplicates.

### Retries

If we don't receive a successful response to webhook event triggers, we'll retry sending the same event with an exponential back-off. You can find the full retry schedule below.

| Attempt     | Delay                   |
| ----------- | ----------------------- |
| 1st attempt | 1 minute                |
| 2nd attempt | 5 minutes               |
| 3rd attempt | 25 minutes              |
| 4th attempt | 2 hours and 5 minutes   |
| 5th attempt | 10 hours and 25 minutes |
