Outbound Webhooks
Outbound webhooks let AffiliateBase notify your own systems when affiliate program activity happens.
Use them when you want to:
- create or update affiliate records in your CRM
- notify your team when an affiliate is approved
- sync referrals and conversions into a warehouse
- trigger internal commission review or payout workflows
- keep another system up to date without polling the REST API
Create a webhook endpoint
- Open AffiliateBase.
- Go to Settings -> Webhooks.
- Click Create endpoint.
- Enter a name, such as
Production CRM. - Enter an HTTPS endpoint URL from your app, automation tool, or integration platform.
- Select the event types you want to receive.
- Save the endpoint.
- Copy the signing secret immediately. It is only shown once.
Use a test or staging endpoint first. After your receiver validates signatures and returns successful responses, create the production endpoint.
Available events
AffiliateBase can send events for core affiliate program lifecycle changes:
| Event | When it fires |
|---|---|
affiliate.created | An affiliate record is created |
affiliate.approved | An affiliate moves into the active state |
referral.created | A referral is created from tracking activity |
referral.converted | A referral reaches conversion state |
commission.created | A commission is created from a sale |
commission.due | A commission moves into due state |
commission.voided | A commission is voided |
payout.paid | A payout is marked paid |
Your endpoint only receives events it is subscribed to.
Test delivery
After creating an endpoint:
- Open the endpoint from Settings -> Webhooks.
- Click Send test.
- Check your receiver logs.
- Confirm your endpoint returns a
2xxstatus code.
Test events use the first selected event type on the endpoint and include test: true in the payload.
Payload shape
Webhook requests are JSON.
{
"id": "webhook_event_id",
"type": "commission.created",
"occurred_at": "2026-05-29T14:21:12Z",
"data": {
"id": "commission_id",
"state": "pending",
"amount_cents": 1000,
"currency": "USD",
"affiliate_id": "affiliate_id",
"campaign_id": "campaign_id",
"sale_id": "sale_id",
"sale_customer_email": "customer@example.com",
"sale_customer_name": "Customer Person",
"sale_customer_first_name": "Customer",
"sale_customer_last_name": "Person",
"sale": {
"id": "sale_id",
"customer": {
"email": "customer@example.com",
"name": "Customer Person",
"first_name": "Customer",
"last_name": "Person"
}
},
"created_at": "2026-05-29T14:21:12Z"
}
}
Money amounts are in cents. Timestamps use ISO 8601.
Enrich webhook events with the REST API
Webhook payloads are intentionally compact. For example, commission.created includes the commission ID as data.id, plus fields such as affiliate_id, campaign_id, sale_id, amount, currency, state, and sale customer name/email fields when AffiliateBase has received them.
If your automation needs deeper customer, referral, or affiliate details, use the webhook as the trigger and then call the REST API with the ID from the payload.
For a CRM or automation workflow:
- Trigger the workflow from an AffiliateBase
commission.createdwebhook. - Read the commission ID from
data.id. - Add an HTTP request action in your automation tool or integration code.
- Request:
GET https://app.affiliatebase.io/api/v1/commissions/{commission_id}?account_id={account_id}
Authorization: Bearer {api_key}
GET /api/v1/commissions/:id returns the commission object directly. It includes expanded sale, referral, customer, and affiliate details. Useful fields include:
sale.referral.customer.emailsale.referral.customer.namesale.referral.customer.first_namesale.referral.customer.last_namesale.referral.stripe_customer_idsale.affiliate.idsale.affiliate.emailsale.affiliate.first_namesale.affiliate.last_name
Customer email is available when AffiliateBase receives it from Stripe or your conversion tracking flow. Customer name is included when available. Phone is not currently a standard AffiliateBase customer field, so use Stripe or your CRM as the source for phone numbers.
Signed requests
AffiliateBase signs each webhook request with Svix-style headers:
svix-idsvix-timestampsvix-signature
Verify the signature before processing the event.
The signed content is:
svix-id.svix-timestamp.raw_request_body
The signature uses HMAC SHA-256 and your endpoint signing secret.
Example verification in Node.js
import crypto from "node:crypto";
function verifyAffiliateBaseWebhook({ rawBody, headers, signingSecret }) {
const messageId = headers["svix-id"];
const timestamp = headers["svix-timestamp"];
const signatureHeader = headers["svix-signature"] || "";
const expected = crypto
.createHmac("sha256", signingSecret)
.update(`${messageId}.${timestamp}.${rawBody}`)
.digest("base64");
const received = signatureHeader.replace(/^v1,/, "");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
);
}
Use the raw request body exactly as received. Parsing and re-stringifying JSON before verification will change the signature input.
Delivery logs and retry
AffiliateBase stores delivery attempts for each endpoint.
Open an endpoint in Settings -> Webhooks to see:
- event type
- delivery state
- attempt count
- last HTTP status or error code
- recent delivery history
If a delivery fails, fix the receiver and click Retry.
Receiver requirements
Your endpoint should:
- accept
POSTrequests withContent-Type: application/json - verify the signature before doing work
- return a
2xxstatus code after the event is accepted - process events idempotently by webhook event
id - finish quickly and hand off slow work to a background job
AffiliateBase treats non-2xx responses as failed deliveries.
Security notes
- Use HTTPS for production endpoints.
- Store the signing secret in your server-side secrets manager.
- Do not expose the signing secret in client-side code.
- Reject requests with missing or invalid signatures.
- Keep a replay window for
svix-timestamp, such as five minutes. - Make your receiver idempotent so retries do not duplicate work.