Skip to main content
Webhooks let you receive notifications when payout activity happens — without polling. You subscribe a callback URL to an event type, and Karat sends an HTTP POST to that URL whenever the event occurs.

Subscribe to an event

1

Discover available events

Call GET /events to list the event types you can subscribe to.
2

Create a subscription

Call POST /events/subscription with the event_name and your callback_url. The response includes a secret — store it to verify future deliveries.
3

Acknowledge deliveries

Respond with a 2xx status so Karat knows the event was received.

Secret generation

Karat generates a unique signing secret when you create a subscription. The secret is returned only once in the create subscription response — store it securely so you can verify deliveries.

Handshake verification

When creating a subscription, the API verifies ownership of the callback URL by performing a challenge-response handshake. Your server must handle this before the subscription is accepted. The API sends a POST request to your callback_url with a JSON body:
Your server must respond within 30 seconds with HTTP status 200 and a JSON body echoing the challenge:
If verification succeeds, the subscription is created. If it fails, the API returns a 400 error with one of these messages:

Event types

Payload

Every delivery shares the same envelope — id, event, created_at, subscription_id, and an event-specific data object.

payout.updated

tax_form.created

recipient.updated

Sent as a recipient moves through onboarding. The status field carries the milestone: Each milestone is sent at most once per onboarding invitation — repeating a step (for example, re-signing a tax form) does not produce another event. The tax_info_collected event is never sent for recipients you configured with tax collection disabled; those recipients go straight from onboarding_started to onboarding_completed.
first_name, last_name, and nickname are nullable. date is the ISO-8601 timestamp of when the milestone occurred.

Verify webhook signatures

Every delivery is signed so you can confirm it came from Karat. Verify the signature before processing the payload. Each request includes these headers: The signature is an HMAC-SHA256 of timestamp + "." + raw_body, keyed with your subscription secret, then base64-encoded:
To verify a delivery:
1

Look up the secret

Use X-Karat-Subscription-Id to find the secret you stored when creating the subscription.
2

Check the timestamp

Reject deliveries where X-Karat-Webhook-Timestamp is outside a ±300 second window to protect against replays.
3

Recompute and compare

Recompute the signature from the raw request body and compare it to the value in X-Karat-Signature using a constant-time comparison.
4

Deduplicate

Use X-Karat-Webhook-Id (and the id in the body) to ignore duplicate deliveries.
Compute the signature over the exact raw bytes you received, before any JSON parsing or re-serialization — reformatting the body will change the signature. If verification fails, return a non-2xx response and do not process the event.

Delivery

  • Deliveries are sent asynchronously and retried on failure.
  • Always return a 2xx response quickly; do heavy processing out of band.

Manage subscriptions