Webhooks facilitate a soft real-time notification system, allowing our Rafiki web services to communicate directly with your servers.

By leveraging the HTTP protocol, event notifications are sent directly to your specified secure URL without the need for you to use less efficient polling methods.

The complete list of supported webhook events categorized by resource can be found in the dedicated category section for events.

Lifecycle

The sequence diagram below demonstrates the lifecycle of a webhook event, using a common example: event notifications for successful or failed payouts. Please note that webhooks aren't limited to this scenario.

Webhook lifecycle

  1. In the first iteration, your application instructs Rafiki to initiate a payout.
  2. Rafiki responds, acknowledging the payout request and queues its execution.
  3. Rafiki processes the payout, this is a time-consuming operation.
  4. When the payout is completed, Rafiki notifies your app.
  5. Your app confirms the successful event receipt by responding with an HTTP 2xx status code. This step is crucial for Rafiki to acknowledge receipt and prevent further attempts to send the event (see retries).

Anatomy of a webhook

Webhook events will be formatted as JSON, containing the necessary metadata for your application to accurately handle the specific events. This includes a secure mechanism for authenticating the message, guaranteeing that events are genuine and originate from us.

The raw HTTP message below illustrates how a webhook event looks like:

POST /events HTTP/1.1
Host: example.com
User-Agent: Rafiki-Webhooks/1.0
Content-Type: application/json
X-Rafiki-Webhook-Type: resource.event-type
X-Rafiki-Webhook-Signature: t=1700236724, v1=68ec7b5f585c8d44221a3e3a367b3a83ecd2c9a2e32a4a5614ab2638c51c819f

{
  "id": "wbh-xxx",
  "type": "resource.event-type",
  "data": {...},
  "created_at": "2023-11-21T10:34:23Z"
}

X-Rafiki-Webhook-Type

This field serves to identify the event type, guiding the structure of the "data" property within the body.

X-Rafiki-Webhook-Signature

Contained within this field are the signature(s) used to validate the legitimacy of the Webhook.

Request Body

At the root level of the request body, you will always find the following properties:

  • id: Uniquely identifies the webhook, allows you to reject potential duplicate events.
  • type: Same as X-Rafiki-Webhook-Type, this property determines the structure of the "data" property.
  • data: The specific data relevant to the webhook event. Its value depends on the specific "type"
  • created_at: Indicates the timestamp of the webhook's original creation (NOT send time).

Security first

First and foremost you should only accept Rafiki's webhooks coming from the following IP addresses :

34.242.123.185
54.195.235.178
63.35.15.80

As an extra layer of security, you should ensure that the webhooks indeed originate from us by utilizing the security header X-Rafiki-Webhook-Signature.

This header comprises a Unix timestamp t=, representing the time when the webhook was signed and immediately sent through. It also includes a series of hex-encoded signatures v1=, computed using HMAC-256 with keys that have been pre-shared between us. The v1 denotes the version of the scheme/algo used to compute the signature, allowing for future updates if necessary.

t=1700236724, v1=68ec7b5f585c8d44221a3e3a367b3a83ecd2c9a2e32a4a5614ab2638c51c819f, v1=cb9ddf25bb551017085b79c615904730544776a65f010fd3e0d88390e3553ff1
  \________/     \______________________________________________________________/     \______________________________________________________________/
    unix ts                               signature 1                                                          signature N

ℹ️

Multiple signatures ?

If a key change for signing the webhook has been requested, multiple signatures will be sent.

In this scenario, the old key(s) will be retained for 24 hours. We will sign the webhook with each of the old keys until their expiration.

This provides your application with an extended window to continue functioning with the old key(s) until the new one is configured and deployed.

Verify signature

Presuming the following webhooks comes through, signed with the shared key secret :

....
X-Rafiki-Webhook-Signature: t=1701963863, v1=28f82091581c47530a8fac168ba534e00b9ffd88531d64199c058fc6df39fc71

{"id":"wbh-xxx","type":"foo.baz","data":{},"created_at":"2023-11-21T10:34:23Z"}
  1. Firstly, get the value of the security header and extract its t='s value.

  2. Then, create the message to sign by concatenating :

  • The timestamp t= (1701963863)
  • The character .
  • The actual JSON payload (The raw HTTP body)

message = '1701963863.{"id":"wbh-xxx","type":"foo.baz","data":{},"created_at":"2023-11-21T10:34:23Z"}'

  1. Re-compute the signature using HMAC_SHA256 and your signing key (in this case secret)

signature = HMAC_SHA256('secret', message)

  1. Convert the signature into a hexadecimal string

hex_signature = HEX_STRING(signature)

  1. Compare your computed hex_signature with those attached to the webhook, removing their v1= prefix. If any of the signatures match, the webhook is legitimate.

Retries

If a webhook delivery fails, we'll make up to three additional attempts, following these specific delays:

Retry attemptDelay
1stnone
2nd~ 60 seconds
3rd~120 seconds

A webhook is considered undelivered if there's a transport problem (like timeouts or DNS issues) or if your application responds with a non-2XX status code.

Setup your webhook integration

To set up your webhook integration, you can use the web portal and follow the instructions provided on this page.