Skip to main content

Outbound Webhooks

Send signed AffiliateBase events to your CRM, data warehouse, automation workflow, or internal system

Table of Contents

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

  1. Open AffiliateBase.
  2. Go to Settings -> Webhooks.
  3. Click Create endpoint.
  4. Enter a name, such as Production CRM.
  5. Enter an HTTPS endpoint URL from your app, automation tool, or integration platform.
  6. Select the event types you want to receive.
  7. Save the endpoint.
  8. 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:

EventWhen it fires
affiliate.createdAn affiliate record is created
affiliate.approvedAn affiliate moves into the active state
referral.createdA referral is created from tracking activity
referral.convertedA referral reaches conversion state
commission.createdA commission is created from a sale
commission.dueA commission moves into due state
commission.voidedA commission is voided
payout.paidA payout is marked paid

Your endpoint only receives events it is subscribed to.

Test delivery

After creating an endpoint:

  1. Open the endpoint from Settings -> Webhooks.
  2. Click Send test.
  3. Check your receiver logs.
  4. Confirm your endpoint returns a 2xx status 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:

  1. Trigger the workflow from an AffiliateBase commission.created webhook.
  2. Read the commission ID from data.id.
  3. Add an HTTP request action in your automation tool or integration code.
  4. 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.email
  • sale.referral.customer.name
  • sale.referral.customer.first_name
  • sale.referral.customer.last_name
  • sale.referral.stripe_customer_id
  • sale.affiliate.id
  • sale.affiliate.email
  • sale.affiliate.first_name
  • sale.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-id
  • svix-timestamp
  • svix-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 POST requests with Content-Type: application/json
  • verify the signature before doing work
  • return a 2xx status 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.