Webhook event reference
Every event you can tick on Integrations › Webhooks (or subscribe to through
POST /server/hooks), when Refficks sends it, and what each delivery's
program, typed objects and data carry. For a developer writing the
receiver. How to add an endpoint and verify the signature is in
Receive Refficks events with webhooks.

The envelope every event shares
Every delivery has the same eleven keys, and a key that does not apply is
null:
| Key | What it holds |
|---|---|
id |
{event}:{subject id}. See The id repeats for some events. |
event |
The event, such as payout.paid. |
event_label |
Its name on the screen, such as "Payout paid". |
occurred_at |
When Refficks built the delivery, ISO 8601. The same on every retry and on Send again. |
partner |
The partner it is about: the Server API's partner object, plus display_name and dashboard_url. For referral events, the referrer. Always present. |
program |
{ "id", "name" } of the program it belongs to, or null (the tables below say when it is filled). |
commission |
The Server API's commission_entry, on commission events. |
payout |
The Server API's payout, on payout.paid. |
referral |
id, status, source, signed_up_at, qualified_at, on referral events. |
lead |
id, status, source, company_name, created_at, on lead events. |
data |
Extra detail for that event, listed below. An empty list, [], when the event has nothing extra. |
Money in data is an integer in minor units beside its currency, as
everywhere in the API. Never in any delivery: a partner's scores, payout
details beyond the masked hint, anything about a referred friend, or a lead's
contact details.
The id repeats for some events
id is the event and the id of the one thing it is about. For the events
marked unique below, that thing is a commission, payout, membership,
referral or lead, so id alone names one fact. For the others it is the
partner, so the second tier change for a partner, or every stage change of
every deal they are on, carries the same id as the first.
So deduplicate on id and occurred_at together. Both are unchanged by
a retry or by Send again, and occurred_at tells two different facts
with one id apart. X-Refficks-Delivery names one delivery, not one fact:
Send again gives it a new value.
Partners
| Event | Sent when | id |
program |
data |
|---|---|---|---|---|
partner.applied |
Somebody applies to one of your programs: on its signup page, from the partner directory, or by confirming an application. | unique (the membership) | the program applied to | program_id |
partner.approved |
A partner is approved, or is added already approved (by hand under Partners, or through the Server API). | per partner | null |
from, to (lifecycle stages) when approved from applicant or rejected; [] when created approved |
partner.onboarded |
A partner's lifecycle stage moves to onboarded. | per partner | null |
from, to |
partner.became_dormant |
A partner's lifecycle stage moves to dormant. | per partner | null |
from, to |
partner.first_click |
The first click ever on any of the partner's links. Once per partner. | per partner | null |
[] |
partner.first_conversion |
The first sale ever credited to the partner. Once per partner. | per partner | null |
amount, currency of that sale |
partner.tier_changed |
A partner is moved to another tier in a program, or given or taken off one. | per partner | the program | program_id, from_tier, from_tier_rank, to_tier, to_tier_rank, direction |
partner.tier_eligible |
Refficks finds the partner meets a higher tier's requirements. It proposes the move; a person makes it. Once per tier. | per partner | the program | tier (id, name, rank), current_tier (name, rank, or null), program_id |
direction is promotion, demotion, assigned (they had no tier),
removed (they now have none) or unchanged. Tier names are the names you
gave them; null where there is no tier on that side.
Money
| Event | Sent when | id |
program |
Typed object | data |
|---|---|---|---|---|---|
commission.earned |
Refficks works out a commission on a sale. | unique (the entry) | the commission's | commission, with "status": "pending" |
amount, currency |
commission.reversed |
A refund, dispute or credit note takes some or all of a commission back. One per reversal, so a partial refund and a later one are two deliveries. | unique (the reversal) | the commission's | commission: the reversal entry, with a negative amount and parent_entry_id naming the original |
amount (positive: what came off), currency, reason |
payout.paid |
A payout is marked paid, by a person or when PayPal, Tremendous or a store confirms it. | unique (the payout) | null |
payout |
amount, currency, payout (reference, destination: the masked hint) |
commission.earned is never a promise of money: the entry is pending until
somebody approves it, and a later refund can reverse it. Bonuses, adjustments
and recruiter shares are written without a webhook. Tell a partner they have
been paid on payout.paid, never on commission.earned.
Referrals
These need the referral module. partner is the referrer; nothing about the
friend is sent.
| Event | Sent when | id |
program |
data |
|---|---|---|---|---|
referral.signed_up |
Somebody signs up through a referrer. | unique (the referral) | the referral's | referral (id, status, program_id, source) |
referral.qualified |
The referral counts, by your program's rule. | unique | the referral's | referral, and amount, currency of the referrer's reward (null when there is none) |
referral.rejected |
The referral is refused. | unique | the referral's | referral |
referral.expired |
The referral's window closed without it counting. | unique | the referral's | referral |
referrer.first_referral |
A referrer's first referral of any kind. | unique | the referral's | referral |
referrer.milestone_reached |
A referrer's successful referrals reach 1, 3, 5, 10, 25 or 50. | unique | the referral's | referral, and referrer (successful_referrals, milestone) |
Leads, deal registrations and opportunities
These need the agency and B2B module. A lead or registration nobody sourced sends nothing.
| Event | Sent when | id |
program |
data |
|---|---|---|---|---|
lead.created, lead.qualified, lead.rejected |
A partner submits a lead; it is qualified; it is refused. | unique (the lead) | the lead's | lead (id, status, source, estimated_value, has_company, company_name) |
deal_registration.submitted, .approved, .rejected, .expired |
A partner registers a deal; it is approved or refused; its protection window closes. | per partner | null |
deal (id, status, company_name, estimated_value, protection_days_left, had_conflict) |
opportunity.created |
An opportunity is created. One delivery per partner on it. | per partner | null |
opportunity (id, name, stage, amount, currency, relationship, is_partner_sourced) |
opportunity.stage_changed, .closed_won, .closed_lost |
It moves stage, is won or is lost. One delivery per partner on it. | per partner | null |
opportunity, with from_stage and to_stage added |
partner.first_closed_won |
The first deal a partner is on is won. Once per partner. | per partner | null |
opportunity, milestone (first_closed_won) |
partner.pipeline_threshold_reached |
A partner's open deals they sourced, in one currency, pass the threshold (USD 50,000, EUR 50,000, GBP 40,000 and the like). Once per threshold. | per partner | null |
opportunity, milestone, open_sourced_pipeline, threshold, currency |
An opportunity's amount is what the deal might be worth, not money
received. Revenue arrives as an invoice.paid from your billing system, and
earns commission there.
Creator collaborations
These need the creator module. None fills program.
| Event | Sent when | id |
data |
|---|---|---|---|
collaboration.creator_invited |
A creator is invited to a collaboration. | per partner | collaboration_id |
collaboration.creator_accepted, .creator_declined |
The creator answers. | per partner | collaboration_id |
collaboration.creator_completed |
Everything the creator owed on it is approved or published. | per partner | collaboration_id, deliverables (how many) |
content.submitted |
The creator sends work for review. Each version is its own delivery. | per partner | deliverable_id, collaboration_id, version |
content.revision_requested, content.approved |
You ask for changes, or approve it. A rejection sends nothing. | per partner | deliverable_id, collaboration_id, version |
content.published |
The published post's address is recorded, by the creator in their portal or by you. | per partner | deliverable_id, collaboration_id, url |
deliverable.due_soon |
A deliverable is due within 48 hours (checked hourly). | per partner | deliverable_id, collaboration_id, name, due_at |
deliverable.overdue |
Its due date has passed (checked hourly). | per partner | the same |
content.rights_expiring |
The collaboration's usage rights end within 14 days (checked hourly). One delivery per creator who accepted. | per partner | collaboration (its name), rights_end_at |
content.rights_expired |
The usage rights have ended. | per partner | the same |
Events you will not receive
- Nothing from before the endpoint existed, and nothing an import from another platform brought in.
- Nothing from a closed account until it is reopened.
partner.reached_milestoneand scheduled rules exist for automations but are not offered here: nothing sends the first, and the second is a timer, not a fact.- A sale itself. Sales arrive from your billing system or
your server; a webhook tells you what
Refficks made of one (
commission.earned), not that it arrived.
Samples while you build
GET /server/hooks/samples?event=commission.earned, with a secret key,
returns up to three of your own recent facts in exactly the delivery shape, so
you can build a receiver against real data before anything new happens. See
Subscriptions made through the Server API.
Related
- Receive Refficks events with webhooks — adding an endpoint, the signature, retries and pausing.
- The Server API — the partner, commission and payout objects in full.
- Why are Refficks webhook deliveries failing? — when nothing arrives.
- Automations — the same events, used to send emails and run rules inside Refficks.