Integrations

Signed webhooks delivered in order

AffiliateRail sends a signed HTTP POST to your endpoint when something happens: a partner is approved, a referral converts, a commission is earned, a payout settles or fails. Thirty-eight event types, in the vocabulary affiliate software already uses. Verify one signature, answer 2xx within ten seconds, and de-duplicate on the event id.

Published 3 September 2026. Every claim on this page was read off the documentation linked below on 3 September 2026. Written by Jimi Barkway, who built AffiliateRail. Jimi has run affiliate programs from both sides of the link. Corrections go to support@affiliaterail.com.

A signed webhookEvery webhook carries a timestamped HMAC signature in the Rail-Signature header, so the receiver can verify it came from AffiliateRail and was not replayed.Rail-Signaturetimestamp inside the signatureverified on arrivalA stale delivery fails verification; a rotated secret keeps a grace window.

01 The request

What does a delivery look like?

A JSON body with four keys: id, type, created_at and data. Ids are prefixed strings. Money is an integer in minor units with a currency beside it. Times are ISO 8601 in UTC.

The headers carry the signature, the event type, the event id and the attempt number. The same event keeps the same id across retries and replays. The three Standard Webhooks headers are there too, so an off-the-shelf library can verify it.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
Rail-Signature: t=1756728000,v1=5f1c6c...e2a9
Rail-Event: commission.created
Rail-Event-Id: evt_4Kp2Qw9eRt7YuIoP1aSdFg
Rail-Attempt: 1
webhook-id: evt_4Kp2Qw9eRt7YuIoP1aSdFg
webhook-timestamp: 1756728000
webhook-signature: v1,g0hM9SsE...JEE=

{"id":"evt_4Kp2Qw9eRt7YuIoP1aSdFg",
 "type":"commission.created",
 "created_at":"2026-09-01T12:00:00.000Z",
 "data":{...}}
One delivery. Rail-Signature carries a timestamp and an HMAC. The three webhook-* headers are the Standard Webhooks form.

02 Verification

How do I verify a delivery?

Split Rail-Signature on commas. Take t and every v1. Build the signed string: the timestamp, a dot, and the raw body exactly as received. Compute HMAC-SHA256 with the whole secret, whsec_ prefix included, hex-encoded. Compare in constant time. Reject if t is more than five minutes from your clock.

The docs have it in Node, Python and PHP. Rotating a secret keeps the old one signing for 24 hours, so a rotation is never an outage.

The recipe

  • Split the header

    t, and every v1. There is normally one.

  • Sign the raw body

    The timestamp, a dot, the body as received. Never re-serialise the JSON.

  • Compare in constant time

    Any v1 match is valid. Reject a t more than five minutes from your clock.

03 Retries

What happens when my endpoint is down?

Anything but a 2xx within ten seconds is a failed attempt. Retries wait one minute, five, thirty, two hours, twelve, then a day, then another day. Eight attempts, about 63 hours, which covers a weekend. After that the delivery is marked failed and stays in the log.

From the log you can replay one delivery, everything that failed since a point in time, or a window of up to 30 days. A replay keeps the original event id, so your de-duplication drops the copy.

Eight attempts

  • Minutes

    1, then 5, then 30.

  • Hours

    2, then 12.

  • Days

    1, then 1 more. Then failed, and kept in the log to replay.

Step by step

An endpoint in four steps

Settings, Webhooks. Partners get the same mechanism from their portal, under Settings, Postbacks.

  1. Add an endpoint

    Settings, Webhooks, Add endpoint. A public https address. Tick the event types you want. Nothing ticked means everything.

  2. Copy the secret

    Shown exactly once. If you lose it, rotate it. The new secret signs alongside the old one for 24 hours.

  3. Verify, then answer fast

    Check the signature before you trust the body. Answer 2xx within ten seconds and do slow work after.

  4. Send a test

    Settings, Webhooks, Send a test. The event id starts evt_test_, and the log shows the status code your endpoint returned.

Said plainly

What it does, and does not do

Both lists are read off the same docs pages as everything else here.

It does

  • Signs every delivery

    A timestamped HMAC-SHA256 in Rail-Signature, plus the Standard Webhooks headers with the same secret.

  • Delivers in order, per endpoint

    One request at a time in emission sequence. A sale.created always precedes the commission.created it produced.

  • Retries for about 63 hours

    Eight attempts on a widening schedule, then marked failed and kept in the log.

  • Replays from the log

    One delivery, everything failed since a time, or a 30-day window. Same event id, new delivery id.

  • Gives partners the same mechanism

    Postbacks from the portal, for their own referral, commission and payout events only. Never a customer's email.

It does not

  • Follow redirects

    A 3xx is a failed attempt.

  • Deliver to private addresses

    Loopback, link-local and internal hostnames are refused when saved and again at send time.

  • Promise exactly once

    At least once. If a worker dies between your 200 and our bookkeeping, you may see an event twice. De-duplicate on id.

  • Retry test events

    A test delivery is sent once and shown with its status code.

Questions

Common questions

Which events are there?

Thirty-eight types across partners, applications, links, coupons, referrals, sales, commissions, payouts, risk flags and customers. The names follow the vocabulary most affiliate software uses, so an existing handler keeps working.

How long do I have to respond?

Ten seconds, with any 2xx. Do slow work after you respond. A timeout counts as a failure and is retried.

Can I use a Standard Webhooks library?

Yes. Every delivery carries webhook-id, webhook-timestamp and webhook-signature, signed with the same secret in the form those libraries expect.

What do partners receive?

Only events whose partner_id is theirs, from the referral, commission and payout families, with no customer email. Same signature, same headers, same verifier.

Sources

Where these facts come from

Every claim on this page was read off the product's own documentation on the date shown. The docs change with the product, and then this page is behind until we fix it. Email support@affiliaterail.com and we will correct it and move the date.

Start

Fourteen days to see it work, with nothing on the line

No card. Cancel in one click. Full refund within 30 days of your first payment.