> For the complete documentation index, see [llms.txt](https://partner.doc.bunq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://partner.doc.bunq.com/documentation/bunq-as-a-service/chapter-3-webhooks.md).

# Chapter 3: Webhooks

> 📝 **Last updated:** 2026-02-24\
> See related changes in [Changelog](/changelog/changelog.md#id-2026-02-24)

Instead of polling, you can subscribe to webhook notifications to receive real-time updates about provision status changes or when compliance information inquires are created, or payments/cards etc.

## Subscribing to Webhooks

## Create/Update/Delete Notification Filter URLs

> Create, update, or delete webhook endpoints to receive notifications for specific events.\
> \
> \*\*Important Notes:\*\*\
> \- This endpoint completely \*\*replaces\*\* all existing notification filters for the user\
> \- To \*\*add\*\* notifications: Include all existing + new filters in the request\
> \- To \*\*update\*\* notifications: Include all filters with updated settings  \
> \- To \*\*delete all\*\* notifications: Send empty array \`{}\`\
> \- To \*\*add\*\* notifications for the UserProvisions -> create a session for the user, and use the UserApiKey.id as the "userId" in the request URL\
> \
> \*\*Examples:\*\*\
> \- Current: 3 notification types configured\
> \- To add 1 more: Send POST with all 4 types (3 existing + 1 new)\
> \- To remove 1: Send POST with 2 types (excluding the unwanted one)\
> \- To clear all: Send POST with \`{"notification\_filters": \[]}\`<br>

```json
{"openapi":"3.1.0","info":{"title":"bunq Partner API","version":"1.0.0"},"tags":[{"name":"Notification Management","description":"Webhook notification filter URL management"}],"servers":[{"url":"https://partner-api.sandbox.bunq.com","description":"Sandbox Partner API Server"},{"url":"https://api.partner.bunq.com","description":"Production Partner API Server"}],"security":[{"SessionAuth":[]},{"ClientSignature":[]}],"components":{"securitySchemes":{"SessionAuth":{"type":"apiKey","in":"header","name":"X-Bunq-Client-Authentication","description":"Session token received from POST /session-server"},"ClientSignature":{"type":"apiKey","in":"header","name":"X-Bunq-Client-Signature","description":"HMAC-SHA256 signature of request body using private key"}},"parameters":{"CacheControl":{"name":"Cache-Control","in":"header","required":false,"schema":{"type":"string","default":"no-cache"}},"UserAgent":{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},"BunqLanguage":{"name":"X-Bunq-Language","in":"header","required":false,"schema":{"type":"string","default":"en_US"}},"BunqRegion":{"name":"X-Bunq-Region","in":"header","required":false,"schema":{"type":"string","default":"NL"}},"BunqGeolocation":{"name":"X-Bunq-Geolocation","in":"header","required":false,"schema":{"type":"string"}},"BunqClientRequestId":{"name":"X-Bunq-Client-Request-Id","in":"header","required":false,"schema":{"type":"string"}},"BunqClientAuthentication":{"name":"X-Bunq-Client-Authentication","in":"header","required":true,"schema":{"type":"string","description":"Session token from POST /session-server"}},"BunqClientSignature":{"name":"X-Bunq-Client-Signature","in":"header","required":true,"schema":{"type":"string","description":"HMAC-SHA256 signature of request"}}},"schemas":{"Error":{"type":"object","properties":{"Error":{"type":"array","items":{"type":"object","properties":{"error_description":{"type":"string"},"error_description_translated":{"type":"string"}}}}}}}},"paths":{"/user/{userId}/notification-filter-url":{"post":{"tags":["Notification Management"],"summary":"Create/Update/Delete Notification Filter URLs","description":"Create, update, or delete webhook endpoints to receive notifications for specific events.\n\n**Important Notes:**\n- This endpoint completely **replaces** all existing notification filters for the user\n- To **add** notifications: Include all existing + new filters in the request\n- To **update** notifications: Include all filters with updated settings  \n- To **delete all** notifications: Send empty array `{}`\n- To **add** notifications for the UserProvisions -> create a session for the user, and use the UserApiKey.id as the \"userId\" in the request URL\n\n**Examples:**\n- Current: 3 notification types configured\n- To add 1 more: Send POST with all 4 types (3 existing + 1 new)\n- To remove 1: Send POST with 2 types (excluding the unwanted one)\n- To clear all: Send POST with `{\"notification_filters\": []}`\n","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer"},"description":"User ID"},{"$ref":"#/components/parameters/CacheControl"},{"$ref":"#/components/parameters/UserAgent"},{"$ref":"#/components/parameters/BunqLanguage"},{"$ref":"#/components/parameters/BunqRegion"},{"$ref":"#/components/parameters/BunqGeolocation"},{"$ref":"#/components/parameters/BunqClientRequestId"},{"$ref":"#/components/parameters/BunqClientAuthentication"},{"$ref":"#/components/parameters/BunqClientSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["notification_filters"],"properties":{"notification_filters":{"type":"array","description":"Array of notification filters to create","items":{"type":"object","required":["category","notification_target"],"properties":{"category":{"type":"string","enum":["PARTNER_USER_PROVISION","USER_ONBOARDING","USER_INFORMATION_INQUIRY","PAYMENT","CARD","CARD_TRANSACTION_SUCCESSFUL","CARD_TRANSACTION_FAILED","MUTATION"],"description":"Notification category to filter"},"notification_target":{"type":"string","format":"uri","description":"The webhook URL to receive notifications"}}}}}}}}},"responses":{"200":{"description":"Notification filter URLs created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"Response":{"type":"array","items":{"type":"object","properties":{"NotificationFilterUrl":{"type":"object","properties":{"category":{"type":"string","enum":["PARTNER_USER_PROVISION","USER_ONBOARDING","USER_INFORMATION_INQUIRY","PAYMENT","CARD","CARD_TRANSACTION_SUCCESSFUL","CARD_TRANSACTION_FAILED","MUTATION"],"description":"Notification category"},"all_user_id":{"type":"array","items":{"type":"integer"},"description":"List of user IDs this filter applies to (typically empty)"},"all_monetary_account_id":{"type":"array","items":{"type":"integer"},"description":"List of monetary account IDs this filter applies to (typically empty)"},"all_verification_type":{"type":"array","items":{"type":"string"},"description":"List of verification types (typically empty)"},"notification_target":{"type":"string","format":"uri","description":"The webhook URL to receive notifications"}}}}}}}}}}},"400":{"description":"Bad request - invalid URL or category","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Callback Categories

<details>

<summary>Callback Categories</summary>

#### Partner User Provision

| Category                 | Event Type                               | Explanation                                  |
| ------------------------ | ---------------------------------------- | -------------------------------------------- |
| `PARTNER_USER_PROVISION` | `PARTNER_USER_PROVISION_PROCESS_UPDATED` | Partner user provisioning properties changed |
| `USER_ONBOARDING`        | `USER_ONBOARDING_UPDATED`                | `User onboarding process status updated`     |

#### Compliance Inquiry

<table><thead><tr><th>Category</th><th width="263.134521484375">Event Type</th><th>Explanation</th></tr></thead><tbody><tr><td><code>USER_INFORMATION_INQUIRY</code></td><td><code>USER_INFORMATION_INQUIRY_EXPECTING_REPLY_FROM_USER</code></td><td>Compliance inquiry requiring user response</td></tr><tr><td><code>USER_INFORMATION_INQUIRY</code></td><td><code>USER_INFORMATION_INQUIRY_EXPECTING_REPLY_FROM_BUNQ</code> </td><td>Compliance inquiry requiring bunq review</td></tr><tr><td><code>USER_INFORMATION_INQUIRY</code></td><td><code>USER_INFORMATION_INQUIRY_FINALIZED</code></td><td>Compliance inquiry finalized.</td></tr><tr><td><code>SUPPORT</code></td><td><code>SUPPORT_MESSAGE_USER_TEXT_RECEIVED</code></td><td>Message from User via support is received</td></tr></tbody></table>

#### Transactions

| Category   | Event Type              | Explanation                                                |
| ---------- | ----------------------- | ---------------------------------------------------------- |
| `MUTATION` | `MUTATION_CREATED`      | Event where account balance is decreased                   |
| `MUTATION` | `MUTATION_RECEIVED`     | Event where account balance is increased                   |
| `PAYMENT`  | `PAYMENT_CREATED`       | User initiates a payment - sent to sender                  |
| `PAYMENT`  | `PAYMENT_RECEIVED`      | User receives a payment                                    |
| `PAYMENT`  | `PAYMENT_CLAIMED`       | Payment request has been accepted and processed            |
| `PAYMENT`  | `PAYMENT_REJECTED`      | Payment is rejected due to validation or processing issues |
| `PAYMENT`  | `PAYMENT_REVOKED`       | Payment is cancelled before processing                     |
| `PAYMENT`  | `PAYMENT_EXPIRED`       | Payment expires without being processed                    |
| `PAYMENT`  | `PAYMENT_BATCH_CREATED` | Batch payment is created                                   |
| `PAYMENT`  | `PAYMENT_BATCH_REVOKED` | Batch payment is cancelled                                 |

#### Card Transactions

| Category                      | Event Type                         | Explanation                                                                  |
| ----------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- |
| `CARD_TRANSACTION_SUCCESSFUL` | `CARD_PAYMENT_ALLOWED`             | Card payment approved and processed                                          |
| `CARD_TRANSACTION_SUCCESSFUL` | `CARD_WITHDRAWAL_ALLOWED`          | ATM withdrawal approved and processed                                        |
| `CARD_TRANSACTION_SUCCESSFUL` | `CARD_REVERSAL_ALLOWED`            | Merchant successfully reversed the payment                                   |
| `CARD_TRANSACTION_SUCCESSFUL` | `CARD_RESERVATION_ALLOWED`         | Pre-authorization allowed and unfinalized amount is reserved to be collected |
| `CARD_TRANSACTION_SUCCESSFUL` | `CARD_RESERVATION_FINALIZED`       | Pre-authorization is finalized and final amount is determined.               |
| `CARD_TRANSACTION_FAILED`     | `CARD_TRANSACTION_NOT_ALLOWED`     | Card transaction declined for various reasons                                |
| `CARD_TRANSACTION_UPDATED`    | `CARD_PAYMENT_UPDATED`             | Card transaction is updated (potentially amount is changed)                  |
| `CARD_TRANSACTION_UPDATED`    | `CARD_PAYMENT_SETTLED`             | Card transaction received a clearing.                                        |
| `CARD_TRANSACTION_REFUND`     | `CARD_TRANSACTION_REFUND_APPROVED` | Refund requested by the user was approved                                    |
| `CARD_TRANSACTION_REFUND`     | `CARD_TRANSACTION_REFUND_DENIED`   | Refund requested by the user was denied                                      |

#### Card and Tokenization (Apple/Google Pay)

| Category            | Event Type             | Explanation                                                      |
| ------------------- | ---------------------- | ---------------------------------------------------------------- |
| `CARD`              | `CARD_UPDATED`         | Card properties are updated                                      |
| `CARD_TOKENIZATION` | `CARD_TOKEN_ACTIVATED` | Card token activated for wallet                                  |
| `CARD_TOKENIZATION` | `CARD_TOKEN_SUSPENDED` | Card token suspended temporarily                                 |
| `CARD_TOKENIZATION` | `CARD_TOKEN_DELETED`   | Card token removed and permanently deleted                       |
| `CARD_TOKENIZATION` | `CARD_TOKEN_UPDATED`   | Card token details updated, for example expiry date is extended. |

#### Requests

| Category  | Event Type                          | Explanation                                                |
| --------- | ----------------------------------- | ---------------------------------------------------------- |
| `REQUEST` | `REQUEST_INQUIRY_CREATED`           | Payment request sent to someone and is pending acceptance. |
| `REQUEST` | `REQUEST_INQUIRY_ACCEPTED`          | Recipient approved the request.                            |
| `REQUEST` | `REQUEST_INQUIRY_REJECTED`          | Recipient declined the request.                            |
| `REQUEST` | `REQUEST_INQUIRY_REVOKED`           | Payment request cancelled                                  |
| `REQUEST` | `REQUEST_INQUIRY_EXPIRED`           | Payment request expired                                    |
| `REQUEST` | `REQUEST_RESPONSE_CREATED`          | Response to payment request                                |
| `REQUEST` | `REQUEST_RESPONSE_ACCEPTED`         | Response approved                                          |
| `REQUEST` | `REQUEST_RESPONSE_REJECTED`         | Response declined                                          |
| `REQUEST` | `REQUEST_RESPONSE_REVOKED`          | Response cancelled                                         |
| `REQUEST` | `REQUEST_RESPONSE_EXPIRED`          | Response expired                                           |
| `REQUEST` | `REQUEST_RESPONSE_REFUND_REQUESTED` | Refund requested for response                              |
| `REQUEST` | `REQUEST_RESPONSE_REFUNDED`         | Response refunded                                          |

</details>

### Callback Examples

<details>

<summary><strong>Webhook Body Example (<code>USER_INFORMATION_INQUIRY</code>):</strong></summary>

<pre class="language-json"><code class="lang-json">{
    "NotificationUrl": {
        "target_url": "https://your-webhook-endpoint.com/notifications",
        "category": "USER_INFORMATION_INQUIRY",
        "event_type": "USER_INFORMATION_INQUIRY_EXPECTING_REPLY_FROM_USER",
        "object": {
            "UserInformationInquiry": {
                "id": 17,
                "created": "2025-08-13 15:32:55.697184",
<strong>                "updated": "2025-08-13 15:32:55.817014",
</strong>                "user_id": 1358,
                "title": "We need additional information",
                "subtitle": "To continue your bunq experience, please provide the following information.",
                "purpose": "COMPLIANCE_TRANSACTION_MONITORING",
                "all_entry": [
                    {
                        "UserInformationInquiryEntry": {
                            "id": 17,
                            "created": "2025-08-13 15:32:55.755341",
                            "updated": "2025-08-13 15:32:55.755341",
                            "type": "USER_PERSON_SOURCE_OF_FUND",
                            "status": "PENDING",
                            "all_data_submitted": [],
                            "assistant_conversation": {
                                "id": 17,
                                "created": "2025-08-13 15:32:55.750785",
                                "updated": "2025-08-13 15:32:55.750785",
                                "user_id": 1358,
                                "user_subject_id": 1358,
                                "label_user": {
                                    "uuid": "d556bfc8-c1d4-4d79-a758-e3c2f9360546",
                                    "display_name": "New bunqer",
                                    "country": "NL",
                                    "avatar": {...},
                                    "public_nick_name": "New bunqer",
                                    "type": "PERSON"
                                },
                                "assistant_id": 18,
                                "type": "USER_INFORMATION_INQUIRY",
                                "typing_indicator_status": "INACTIVE",
                                "feedback_status": "NONE",
                                "read_status": "READ"
                            },
                            "context": [],
                            "reject_reason": null
                        }
                    }
                ],
                "assistant_conversation": {...}
            }
        }
    }
}
</code></pre>

**Webhook fields:**

**NotificationUrl Object:**

| `target_url` | Your configured webhook endpoint URL                     |
| ------------ | -------------------------------------------------------- |
| `category`   | Notification category (e.g., `USER_INFORMATION_INQUIRY`) |
| `event_type` | Specific event type within the category                  |
| `object`     | The actual object that triggered the notification        |

**UserInformationInquiry Object:**

| `id`                     | Unique identifier for the inquiry                                  |
| ------------------------ | ------------------------------------------------------------------ |
| `created`                | Timestamp when the inquiry was created                             |
| `updated`                | Timestamp when the inquiry was last updated                        |
| `user_id`                | ID of the user for whom the inquiry was created                    |
| `title`                  | Title of the inquiry (e.g., "We need additional information")      |
| `subtitle`               | Subtitle explaining the inquiry purpose                            |
| `purpose`                | Purpose of the inquiry (e.g., `COMPLIANCE_TRANSACTION_MONITORING`) |
| `all_entry`              | Array of inquiry entries with specific information requests        |
| `assistant_conversation` | Conversation details for user interaction                          |

**UserInformationInquiryEntry Object:**

| `id`                     | Unique identifier for the inquiry entry                            |
| ------------------------ | ------------------------------------------------------------------ |
| `type`                   | Type of information requested (e.g., `USER_PERSON_SOURCE_OF_FUND`) |
| `status`                 | Status of the entry (e.g., `PENDING`)                              |
| `all_data_submitted`     | Array of data submitted by the user                                |
| `assistant_conversation` | Conversation context for this specific entry                       |
| `context`                | Additional context information                                     |
| `reject_reason`          | Reason for rejection (if applicable)                               |

</details>

<details>

<summary><strong>Webhook Body Example (<code>PARTNER_USER_PROVISION</code>):</strong></summary>

```http
{
  "NotificationUrl": {
    "target_url": "https://webhook.site/73fef6b5-f7ba-419b-b65f-f66199489903",
    "category": "PARTNER_USER_PROVISION",
    "event_type": "PARTNER_USER_PROVISION_PROCESS_UPDATED",
    "object": {
      "PartnerUserProvision": {
        "id": 7,
        "created": "2025-09-03 08:24:13.795007",
        "updated": "2025-09-03 08:24:14.266407",
        "external_uuid": "f8b69bdd-e2fa-4161-9ff7-f4c597f8be8e",
        "status": "ACTIVE",
        "sub_status": "NONE",
        "action_required": "NONE",
        "products": [
          "USER_ANONYMOUS_TRANSACTION_AUDIT"
        ],
        "label_user": {
          "uuid": "ae92e7da-59d6-4dcd-a99b-0109baa5aebc",
          "display_name": "New bunqer",
          "country": "NL",
          "avatar": {
            "uuid": "353e5068-1254-4422-b949-596b9f86ebeb",
            "image": [
              {
                "attachment_public_uuid": "229705c3-9d5c-424f-abc4-3f84559abd6f",
                "height": 640,
                "width": 640,
                "content_type": "image/png",
                "urls": [
                  {
                    "type": "ORIGINAL",
                    "url": "https://bunq-triage-model-storage-public.s3.eu-central-1.amazonaws.com/bunq_file/File/content/e627dab1418debb69a8ab983e7cd99a7b0cb8c289892dde90a8b2f12d5e23140.png"
                  }
                ]
              }
            ],
            "anchor_uuid": "ae92e7da-59d6-4dcd-a99b-0109baa5aebc",
            "style": "NONE"
          },
          "public_nick_name": "New bunqer",
          "type": "PERSON"
        },
        "oauth_request": {
          "uuid": "c59a2b0d-1a16-4a5e-9ad7-93f4921d5b52",
          "created": "2025-09-03 08:24:14.110949",
          "updated": "2025-09-03 08:24:14.182413",
          "oauth_client_id": 13383,
          "oauth_client_display_name": null,
          "response_type": "code",
          "callback_url": "https://yourpartner.com/oauth/callback",
          "status": "ACCEPTED",
          "state": null,
          "authorization_code": "b967643d4c76956b550553a0ebd94f1024c734d0ebaefdca00d42d1f1bfae274",
          "user_alias_created": {
            "uuid": "490f019f-6e1c-4891-b2de-da9e85a12644",
            "display_name": "Sutton Onderlinge Waarborgmaatschappij",
            "country": "000",
            "avatar": {
              "uuid": "9debf55b-70b1-4d43-8d51-d6e7bd42fb5b",
              "image": [
                {
                  "attachment_public_uuid": "4b7e0d1d-9167-48ac-990a-70e342c87812",
                  "height": 126,
                  "width": 200,
                  "content_type": "image/jpeg",
                  "urls": [
                    {
                      "type": "ORIGINAL",
                      "url": "https://bunq-triage-model-storage-public.s3.eu-central-1.amazonaws.com/bunq_file/File/content/6979a145b7ea9ecc3459358122cb560608f02d36d4b8cd6b770f50e36aa35512.jpg"
                    }
                  ]
                }
              ],
              "anchor_uuid": "490f019f-6e1c-4891-b2de-da9e85a12644",
              "style": "NONE"
            },
            "public_nick_name": "Sutton Onderlinge Waarborgmaatschappij",
            "type": "COMPANY"
          },
          "redirect_url": "https://yourpartner.com/oauth/callback?code=b967643d4c76956b550553a0ebd94f1024c734d0ebaefdca00d42d1f1bfae274",
          "type": "BUNQ"
        },
        "credential": {
          "id": 2412203,
          "created": "2025-09-03 08:24:14.178726",
          "updated": "2025-09-03 08:24:14.178726",
          "status": "PENDING_FIRST_USE",
          "expiry_time": "2025-09-03 09:24:14.178685",
          "token_value": "a0239a79b1a8d4429062bbcbdccf30cfda06eb6a2a8effc041085135e36d63d4",
          "permitted_device": null
        }
      }
    }
  }
}
```

</details>

## Recovering Failed Webhooks <a href="#retry-mechanisms" id="retry-mechanisms"></a>

When the execution of a callback fails (e.g. the callback server is down or the response contains an error), we try to resend it for a maximum of 5 times, with an interval of one minute between each try. If your server is not reachable by the callback after the 6th total try, the callback is not sent anymore.

### Listing of failed Webhooks <a href="#listing-of-failed-callbacks" id="listing-of-failed-callbacks"></a>

After the sixth attempt of callback executing, the failed entry is stored and can be listed by UserApiKey

## List Notification Filter Failures

> Retrieve all notification filter failures that have occurred when trying to deliver webhooks\
> for the given user.\
> \
> The notifications of the underlying users of the partner are linked with the partner's company\
> user. The \`userId\` should be the \`UserCompany.id\` of the partner — the response will include\
> failed notifications for all underlying provisioned users.\
> \
> \*\*Response includes:\*\*\
> \- Failed notification details\
> \- Error descriptions and timestamps\
> \- Response code from the webhook endpoint (or null)\
> \- Associated notification filter configuration<br>

```json
{"openapi":"3.1.0","info":{"title":"bunq Partner API","version":"1.0.0"},"tags":[{"name":"Notification Management","description":"Webhook notification filter URL management"}],"servers":[{"url":"https://partner-api.sandbox.bunq.com","description":"Sandbox Partner API Server"},{"url":"https://api.partner.bunq.com","description":"Production Partner API Server"}],"security":[{"SessionAuth":[]},{"ClientSignature":[]}],"components":{"securitySchemes":{"SessionAuth":{"type":"apiKey","in":"header","name":"X-Bunq-Client-Authentication","description":"Session token received from POST /session-server"},"ClientSignature":{"type":"apiKey","in":"header","name":"X-Bunq-Client-Signature","description":"HMAC-SHA256 signature of request body using private key"}},"parameters":{"CacheControl":{"name":"Cache-Control","in":"header","required":false,"schema":{"type":"string","default":"no-cache"}},"UserAgent":{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},"BunqLanguage":{"name":"X-Bunq-Language","in":"header","required":false,"schema":{"type":"string","default":"en_US"}},"BunqRegion":{"name":"X-Bunq-Region","in":"header","required":false,"schema":{"type":"string","default":"NL"}},"BunqGeolocation":{"name":"X-Bunq-Geolocation","in":"header","required":false,"schema":{"type":"string"}},"BunqClientRequestId":{"name":"X-Bunq-Client-Request-Id","in":"header","required":false,"schema":{"type":"string"}},"BunqClientAuthentication":{"name":"X-Bunq-Client-Authentication","in":"header","required":true,"schema":{"type":"string","description":"Session token from POST /session-server"}},"BunqClientSignature":{"name":"X-Bunq-Client-Signature","in":"header","required":true,"schema":{"type":"string","description":"HMAC-SHA256 signature of request"}}}},"paths":{"/user/{userId}/notification-filter-failure":{"get":{"tags":["Notification Management"],"summary":"List Notification Filter Failures","description":"Retrieve all notification filter failures that have occurred when trying to deliver webhooks\nfor the given user.\n\nThe notifications of the underlying users of the partner are linked with the partner's company\nuser. The `userId` should be the `UserCompany.id` of the partner — the response will include\nfailed notifications for all underlying provisioned users.\n\n**Response includes:**\n- Failed notification details\n- Error descriptions and timestamps\n- Response code from the webhook endpoint (or null)\n- Associated notification filter configuration\n","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID of the partner's company user (UserCompany)."},{"$ref":"#/components/parameters/CacheControl"},{"$ref":"#/components/parameters/UserAgent"},{"$ref":"#/components/parameters/BunqLanguage"},{"$ref":"#/components/parameters/BunqRegion"},{"$ref":"#/components/parameters/BunqGeolocation"},{"$ref":"#/components/parameters/BunqClientRequestId"},{"$ref":"#/components/parameters/BunqClientAuthentication"},{"$ref":"#/components/parameters/BunqClientSignature"}],"responses":{"200":{"description":"List of notification filter failures","content":{"application/json":{"schema":{"type":"object","properties":{"Response":{"type":"array","items":{"type":"object","properties":{"NotificationFilterFailure":{"type":"object","properties":{"id":{"type":"integer","description":"Unique ID of the failure record"},"created":{"type":"string","format":"date-time","description":"When the failure was recorded"},"updated":{"type":"string","format":"date-time","description":"Last update timestamp"},"notification_filters":{"type":"array","description":"The notification filter configuration that triggered this failure. Empty if the filter has since been deleted.","items":{"type":"object","properties":{"notification_delivery_method":{"type":"string","description":"Delivery method of the notification"},"notification_target":{"type":"string","format":"uri"},"category":{"type":"string"}}}},"category":{"type":"string","description":"The category of the failed notification"},"event_type":{"type":"string","description":"The event type of the failed notification"},"object_id":{"type":"integer","description":"The object id used to generate the body of the notification"},"exception_message":{"type":"string","description":"The exception bunq encountered when processing the callback"},"response_code":{"type":["integer","null"],"description":"The response code (or null) received from the endpoint"},"notification_target":{"type":"string","format":"uri","description":"This is the URL to which the callback will be made"}}}}}}}}}}}}}}}}
```

## Retry Failed Notification Deliveries

> Retry delivery of failed webhook notifications by specifying their failure IDs.\
> \
> \*\*Key Features:\*\*\
> \- Retry up to 100 failed notifications in a single request\
> \- Multiple IDs can be provided as comma-separated values\
> \- Only failed notifications belonging to the specified user can be retried\
> \- Successfully queued retries will return the failure IDs that were processed\
> \
> \*\*Use Cases:\*\*\
> \- Retry notifications after fixing webhook endpoint issues\
> \- Bulk retry of failures after maintenance windows\
> \- Recovery from temporary network or service outages<br>

```json
{"openapi":"3.1.0","info":{"title":"bunq Partner API","version":"1.0.0"},"tags":[{"name":"Notification Management","description":"Webhook notification filter URL management"}],"servers":[{"url":"https://partner-api.sandbox.bunq.com","description":"Sandbox Partner API Server"},{"url":"https://api.partner.bunq.com","description":"Production Partner API Server"}],"security":[{"SessionAuth":[]},{"ClientSignature":[]}],"components":{"securitySchemes":{"SessionAuth":{"type":"apiKey","in":"header","name":"X-Bunq-Client-Authentication","description":"Session token received from POST /session-server"},"ClientSignature":{"type":"apiKey","in":"header","name":"X-Bunq-Client-Signature","description":"HMAC-SHA256 signature of request body using private key"}},"parameters":{"CacheControl":{"name":"Cache-Control","in":"header","required":false,"schema":{"type":"string","default":"no-cache"}},"UserAgent":{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},"BunqLanguage":{"name":"X-Bunq-Language","in":"header","required":false,"schema":{"type":"string","default":"en_US"}},"BunqRegion":{"name":"X-Bunq-Region","in":"header","required":false,"schema":{"type":"string","default":"NL"}},"BunqGeolocation":{"name":"X-Bunq-Geolocation","in":"header","required":false,"schema":{"type":"string"}},"BunqClientRequestId":{"name":"X-Bunq-Client-Request-Id","in":"header","required":false,"schema":{"type":"string"}},"BunqClientAuthentication":{"name":"X-Bunq-Client-Authentication","in":"header","required":true,"schema":{"type":"string","description":"Session token from POST /session-server"}},"BunqClientSignature":{"name":"X-Bunq-Client-Signature","in":"header","required":true,"schema":{"type":"string","description":"HMAC-SHA256 signature of request"}}},"schemas":{"Error":{"type":"object","properties":{"Error":{"type":"array","items":{"type":"object","properties":{"error_description":{"type":"string"},"error_description_translated":{"type":"string"}}}}}}}},"paths":{"/user/{userId}/notification-filter-failure":{"post":{"tags":["Notification Management"],"summary":"Retry Failed Notification Deliveries","description":"Retry delivery of failed webhook notifications by specifying their failure IDs.\n\n**Key Features:**\n- Retry up to 100 failed notifications in a single request\n- Multiple IDs can be provided as comma-separated values\n- Only failed notifications belonging to the specified user can be retried\n- Successfully queued retries will return the failure IDs that were processed\n\n**Use Cases:**\n- Retry notifications after fixing webhook endpoint issues\n- Bulk retry of failures after maintenance windows\n- Recovery from temporary network or service outages\n","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"integer"},"description":"User ID who owns the failed notifications"},{"$ref":"#/components/parameters/CacheControl"},{"$ref":"#/components/parameters/UserAgent"},{"$ref":"#/components/parameters/BunqLanguage"},{"$ref":"#/components/parameters/BunqRegion"},{"$ref":"#/components/parameters/BunqGeolocation"},{"$ref":"#/components/parameters/BunqClientRequestId"},{"$ref":"#/components/parameters/BunqClientAuthentication"},{"$ref":"#/components/parameters/BunqClientSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["notification_filter_failed_ids"],"properties":{"notification_filter_failed_ids":{"type":"string","description":"Comma-separated list of notification filter failure IDs to retry.\nMaximum of 100 IDs allowed per request.\n","pattern":"^[0-9]+(,[0-9]+)*$"}}}}}},"responses":{"200":{"description":"Retry successfully queued. Returns an empty response body.","content":{"application/json":{"schema":{"type":"object","properties":{"Response":{"type":"array","items":{}}}}}}},"400":{"description":"Bad request - invalid IDs, too many IDs, or malformed request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found - one or more failure IDs don't exist or don't belong to the user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## **Webhook Security (Optional):**

* Webhooks are sent as POST requests to your configured URL
* Certificate Pinning can be registered for webhooks so that bunq validates that the certificate of the recipient and the certificate shared match.
* For more information -> <https://doc.bunq.com/basics/callbacks-webhooks#certificate-pinning>
* In addition, it is possible to also validate the vice-versa that bunq is the sender. If configured, bunq will send you their certificate which you can validate if its a match upon receiving the webhook.
  * To set this up, upon creation of `notification_filters[]` send also:
  * <pre><code><strong>"all_verification_type": ["BUNQ_CERTIFICATE"]
    </strong></code></pre>
  * bunq will send you the applicable certificate (for sandbox and production) separately

### Receiving Callbacks <a href="#receiving-callbacks" id="receiving-callbacks"></a>

* Callbacks for the sandbox environment will be made from different IP's at AWS.
* Callbacks for the production environment will be made from 185.40.108.0/22.

*The IP addresses might change*. We will notify you in a timely fashion if such a change is planned.

### Certificate Pinning <a href="#certificate-pinning" id="certificate-pinning"></a>

We recommend that you use certificate pinning as an extra security measure. We will check if the certificate of the recipient server matches the pinned certificate that you provided and cancel the callback if the check fails or we detect a mismatch.

#### How to set up certificate pinning <a href="#how-to-set-up-certificate-pinning" id="how-to-set-up-certificate-pinning"></a>

1. Retrieve the SSL certificate of your server using the following command:

   `openssl s_client -servername www.example.com -connect www.example.com:443 < /dev/null | sed -n "/-----BEGIN/,/-----END/p" > www.example.com.pem`
2. `POST` the certificate to the `certificate-pinned`endpoint.

Once ready, every callback will be checked against the pinned certificate that you provided. Note that if the SSL certificate on your server expires or is changed, our callbacks will fail.
