Webhook setup

Below we’ll walk you through the benefits of webhooks and provide a guide to help you configure and integrate with Bud's webhooks.

Having trouble with webhooks? Check out our webhook FAQ.

Prerequisites

Prior to using any of Bud’s webhooks, you must perform the following steps:

  1. Sign up to the Bud Console
  2. Get API Keys and authenticated access
  3. You should now be able to configure webhooks via the Bud Console, but one of following steps are required for us to make calls to your webhooks.
    1. Setup Bud Connect
    2. Setup First Party Ingestion

Why use webhooks at Bud?

The Bud platform hosts various asynchronous API endpoints. This is where you submit a request and then receive a task id in the response. You then make a request to a second endpoint in order to get the status of the task (and sometimes the final result).

There are two methods to know when the task has finished processing: (i) by polling the second endpoint, i.e. making several requests to it every X seconds until a result is provided; or (ii) by receiving a webhook, i.e. Bud will send a request to a specific webhook URL to let you know that the task has finished processing and the result is ready to be collected.

When working with large datasets or where processing the task can take a significant amount of time, polling can be an inefficient method of retrieving the final result. Every time the second endpoint is called when the task hasn't completed processing, compute resources are used by both parties - and if this is repeatedly called, the resource consumption becomes wasteful, this should be avoided.

👍

We recommend that you use the second option, to receive a webhook rather than polling for the result.

Many of our asynchronous endpoints also offer webhooks and will call your configured webhook URL. These webhook can be found in our API Reference on the Bud documentation. By opting to use webhooks, both parties reduce the amount of compute resources that are used when communicating with asynchronous endpoints.

Example:

The POST /v1/open-banking/refresh asynchronous endpoint (here) allows you to initiate the task to retrieve the latest data from a customer account (if the consent exists). You can check the status of the task via the GET /v1/open-banking/refresh/{task_id} endpoint (here). Polling this endpoint repeatedly, when it is not ready, wastefully consumes your compute resources (by making the call) as well as ours (to determine the status). Thankfully, the POST /v1/open-banking/refresh endpoint (here) offers a few webhooks, one of which is the RefreshCompleted webhook. When configured, this webhook will call the webhook URL configured in your Bud Console - letting you know that the refresh has completed as well as various other data.

Example response for RefreshCompleted:

{  
  "data": {  
    "task_id": "030c78b0-617c-4649-9319-e07569362a14",  
    "task_type": "refresh",  
    "customer_id": "82a90a04-4bdf-446a-932e-fb559ea99c29",  
    "status": "Completed",  
    "result": "success",
    "has_new_transactions": "true",
    "reconnect_required": "false",
    "provider": "Bank_Of_Bud"
  }  
}

Configuring webhooks

Configuring webhooks at Bud couldn’t be easier. You can configure this in the Bud Console under the Project page.

By clicking configure on a project, you’ll be presented with an option to Setup a webhook:

You can select the events you would like to subscribe to, and specify the webhook URL you would be using.

Optionally here, you are also able to specify additional headers you would like to be dispatched with your webhook, as well as a signing token discussed below. You can then see a list of registered webhooks, with the option to activate/deactivate them, as well as the option to register webhooks for other URLs. By default, once you subscribe to a webhook it will be set to active.

You may be required to build a webhook service to ensure you are ready to consume webhooks - more details about this can be found below.

Seeing past events

How to integrate with Bud webhooks

You must provide an endpoint that we can call to send data about the webhook (this will be the webhook URL set in the Bud Console). This means that the endpoint must be publicly reachable.

We will also include a payload in the webhook call - the format of the payload will vary depending on the webhook type, however, all webhook payloads follow a similar structure. Below are two currently supported payload types with some sample data:

Open banking aggregation webhooks:

{
  "data": {
    "consent_id": "e8d6beb1-0a3d-42bb-a11b-033e06a1becf",
    "customer_id": "8888ec25-90b0-4ea4-80d8-5173cecf533c",
    "provider": "",
    "result": "success",
    "status": "Completed",
    "task_id": "030c952e-0332-4e0c-8484-9f60ab5596cd",
    "task_type": "connect"
  }
}

Ingestion webhooks

{
  "data": {
    "event": "first_party_ingester.ingest.succeeded",
    "operation_id": "v2_ingest_transactions_post",
    "task_id": "7f86f76f-4c84-4de3-8668-a6d8bd79c356"
  }
}

Webhook signing

All our webhooks are currently provided with an X-Signature and X-Signing-ID header. The X-Signing-ID includes the public key id which should be used to verify the X-Signature header (i.e. the signed request body JWT). A list of public keys can be found in our Bud Webhook Assets.

🚧

Please note this method of webhook signing is to be deprecated on the 18th of November 2024 and will be replaced with the below method.

Webhooks can be signed using HMAC-SHA256. A secret signing token can be defined in the UI when creating a new webhook subscription, or managing subscriptions. This secret signing token must be over 32 characters. The HMAC-SHA256 signature will be hexadecimal encoded, and included with webhooks in the X-Token-Signature header if a secret signing token is set in the subscription.

Below is a brief python script to compute a webhook signature, which could be used to help verify the webhooks came from Bud.

import hashlib
import hmac

signing_token = 'top secret signing token for webhooks'

message = '{"data":{"event":"first_party_ingester.ingest.succeeded","operation_id":"v2_ingest_transactions_post","task_id":"7a07a4d9-4a90-4267-9fbe-064acad7052e"}}'

signature = hmac.new(
    bytes(signing_token, "UTF-8"), 
    msg=bytes(message, "UTF-8"), 
    digestmod=hashlib.sha256
).hexdigest().lower()

print(signature)

Bud webhook support

We are continuing to grow our webhook support, and we will add more over time. The best way to see if an endpoint supports webhooks, is to check the API Reference on the Bud documentation. The most commonly used webhooks are detailed below:

Open banking aggregation webhooks

Open banking connection completed - This will fire when an open banking connect task (in both the TSP and TPP scenarios) either completes or fails. The result field will provide some details as to why a given task may have failed (if the status field is equal to “Failed”).

Open banking refresh completed - This will fire when an open banking refresh task (in both the TSP and TPP scenarios) either completes or fails. The result field will provide some details as to why a given task may have failed (if the status field is equal to “Failed”).

Ingestion webhooks

First party ingester ingest succeeded - This will fire when the status of an ingestion task has succeeded.

First party ingester ingest failed - This will fire when the status of an ingestion task has failed.

📘

You can learn more about First Party Ingestion webhooks here and Connect webhooks here

Retries

Should a webhook fail to deliver to your assigned endpoint we use the following retry logic:

  • Each request is given a timeout of 10 seconds
  • We exponentially backoff between consecutive requests
  • We retry the request up to 10 times

Along with this retry logic, we have a set of status codes which we will attempt to retry, shown in the table below:

Status CodeDescription
408Request timeout
425Request too early
429Too many requests
500Internal server error
502Bad gateway
503Service unavailable
504Gateway timeout

Any other status codes we will not attempt to retry.

📘

Failures due to connection timeouts or broken connections are retried

FAQ

Q: It is difficult to determine from the payload, which webhook is being triggered - how might we determine which webhook was called?

  • A: We suggest clients use a different URL for each webhook. This has the added benefit to the client to scale individual webhook URL endpoints, as it is likely some webhooks will trigger more frequently than others.
  • A: For clients that wish to use a single endpoint - we plan to extend the payloads of our webhook calls to include an event field, to better identify which webhook was triggered.

Q: We have set up a webhook service and are not receiving any calls. What could be the issue?

  • A: Please make sure the endpoint is publicly reachable - we often find clients do not provide a valid and reachable webhook URL - whether because it is only reachable behind a VPN, we are refused access, or the provided URL is not valid.
  • A: If it was working before and has stopped, we will likely be aware of the issue and we will be actively trying to resolve it.




If you have any questions, please contact us via the chatbot (bottom-right of screen 👉) or via a support request or check our FAQs.