Skip to main content

Webhooks

Webhooks are a method for Basis Theory to send real-time data to your application when a specific event occurs. Unlike traditional APIs that require you to request data from Basis Theory, webhooks automatically push data to a designated URL as soon as the event is triggered.

Getting started

There are several general requirements needed to accept webhooks.

Publicly Accessible Endpoint

The webhook receiver must have a publicly accessible URL where Basis Theory can send HTTP requests. This URL will be registered with Basis Theory when you setup the webhook.

The receiver should be capable of handling HTTP POST requests. It's required to use HTTPS to secure the data in transit, protecting it from potential interception.

Signature Verification

Basis Theory will send a signature along with the payload that can be used to verify the authenticity of the request. Signature verification is not a requirement, but is highly recommended. The version of the signature will be in the BT-SIGNATURE-VERSION header in the webhook request.

v1 Signing

The body of the webhook will be signed using an HMAC key. The signing key can be retrieved at https://cdn.basistheory.com/keys/webhooks.v1.key

The signature of each request will be in the BT-SIGNATURE header. It is encoded using base64.

Sample Javascript Signature Verification
const crypto = require('crypto');
const stringify = require('json-stable-stringify');

const verifyWebhook = (webhookRequest) => {
const body = JSON.parse(webhookRequest.request.body);
const signature = webhookRequest.request.headers['BT-SIGNATURE'];
const publicKey = ''; // Retrieve the signing key from https://cdn.basistheory.com/keys/webhooks.v1.key
const verifier = crypto.createVerify('SHA256');

verifier.update(stringify(body));

const isVerified = verifier.verify(
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
},
Buffer.from(signature, 'base64')
);

return isVerified;
};

Response Handling

The webhook receiver should respond to the sending application with an HTTP 2xx status code to acknowledge receipt of the webhook. This informs the Basis Theory that the request was successful. Basis Theory may close the HTTP request if a response is not returned in a timely manner. In this case, the webhook will be retried until the retry limit is reached or a successful response is returned. If your processing will take a while, consider persisting the message to asynchronously process it.

Idempotency

Design the receiver to gracefully handle duplicate requests. Basis Theory may send the same event multiple times. Implementing idempotency ensures that repeated processing of the same request does not lead to unintended side effects.

Replay Attacks

To help guard against replay attacks, each event includes a delivered_at attribute. The delivered_at attribute can be validated to be "close to now". Implementing idempotency is another method to limit the affects of replay attacks.

Register the Webhook

Using the Basis Theory Portal or API, register your webhook and the events that should be sent. Each tenant may have up to five webhook URLs registered at one time.

Disabled Webhooks

If a webhook URL continuously fails delivery, Basis Theory may disable the webhook. Disabled webhooks will need to be manually re-enabled. To re-enable a webhook, use the Update Webhook API When a webhook is disabled by Basis Theory, we will attempt to send an email to the address specified in the notify_email attribute of the webhook.