Documentation

Getting StartedLinkSitesAPI ReferenceWebhooksIntroductionEvent HandlingRequest bodyEvents and Associated PayloadsAPI Change ManagementChangelog

Webhooks

Introduction

Webhooks allow you to receive real-time notifications of the completion events in the Pinwheel system such as Direct Deposit Switch and Direct Deposit Payment.

You can register a webhook by sending a POST request to the /v1/webhooks/ endpoint.

Event Handling

Webhook events are sent with headers to help you verify an event was sent by Pinwheel. They can also be used to ensure idempotency.

X-PINWHEEL-SIGNATURE: str
X-TIMESTAMP: str
X-PINWHEEL-WEBHOOK-UUID: str

Verifying Pinwheel is the sender

The X-PINWHEEL-SIGNATURE header's value can be used to verify Pinwheel was the sender of the event. The signature is generated using HMAC-SHA256 on the payload object within the request body and the X-TIMESTAMP header value in the form v1:{x-pinwheel-timestamp-value}:{request_body_as_str} and signed with your API Key Secret.

# Python
import hmac
import hashlib
signature = request.headers.get('X-PINWHEEL-SIGNATURE')
timestamp = request.headers.get('X-TIMESTAMP')
payload = request.json()["payload"]
sanitized_request_body_as_str = json.dumps(
payload, separators=(",", ":"), ensure_ascii=False,
).strip("\t\n\r")
msg = f"v1:{timestamp}:{sanitized_request_body_as_str}"
generated_hash = hmac.new(
key='YOUR_API_SECRET'.encode('utf-8'),
msg=msg,
digestmode=hashlib.sha256).hexdigest()
)
generated_signature = f"v1={generated_hash}"
is_valid = (signature == generated_signature)
// Javascript
import * as crypto from 'crypto-js';
const signature = request.headers.get('X-PINWHEEL-SIGNATURE');
const timestamp = request.headers.get('X-TIMESTAMP');
const payload = request.json().payload;
const message = `v1:${timestamp}:${JSON.stringify(payload)}`;
const hash = crypto.HmacSHA256(message, 'YOUR_API_SECRET').toString();
const generatedSignature = `v1=${hash}`;
const isValid = (signature === generatedSignature)
}

Handling duplicate events

The X-PINWHEEL-WEBHOOK-UUID header can be used to guard against potential duplicate events to make your system idempotent.

Request body

Webhook request bodies are composed of two sections. The top-level section contains three keys. The payload section, contained in the payload key, contains specific information about the event. See this section for the various payload bodies for each event.

Top-Level

KeyTypeDescription
eventstringEvent type. See webhook events.
webhook_idstringUnique identifier for the object.
payloaddictPayload associated with event type. See webhook events for associated payload object.

Example

{
"event": "job_result",
"webhook_id": uuid,
"payload": {
...
}
}

Events and Associated Payloads

Below is a table of the event names and the associated inner payload body that is returned within the webhook payload.

EventPayload body
direct_deposit_payment.addedA direct_deposit_payment job object. See the job schema for details.
direct_deposit_switch.addedA direct_deposit_switch job object. See the job schema for details.