# AffiliateRail API 2026-08-21 The REST API for AffiliateRail: every object in the product, addressable, on one consistent contract. - **Auth**: `Authorization: Bearer rail_live_…`. Test-mode keys (`rail_test_…`) work against the same organization and stamp `X-Rail-Livemode: false` on every response. - **Lists**: one flat envelope `{ data, has_more, total_count }`; `limit` (default 25, max 100), `starting_after` / `ending_before` cursors; `program_id` required. - **Expand**: `expand[]=partner` embeds the related object under the same name on every endpoint that has it. `include[]=stats` adds computed counters. - **Money**: integer minor units (`amount_minor`) with an explicit `currency`. Rates are basis points. Never floats, never strings. - **Idempotency**: send `Idempotency-Key` on any POST; the same key replays the first response for 24 hours. - **Rate limit**: 25 requests per second per key. `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and `Retry-After` on 429. - **Errors**: `{ error: { type, code, message, param? } }`, every time. - **Webhooks**: the event catalogue and signing scheme are at https://app.affiliaterail.com/webhooks/llms.txt. ## Routes ### GET /v1/programs List programs Every program in your organization. The one list that does not take `program_id`. **Scope:** `read` Parameters: - limit (query) - starting_after (query) - ending_before (query) - include[] (query) ### GET /v1/programs/{id} Retrieve a program **Scope:** `read` Parameters: - id (path, required): Prefixed id (`prg_…`) - expand[] (query): No relations on this resource - include[] (query): Extras to include: stats ### POST /v1/programs/{id} Update a program Settings a merchant can change from the API. Portal branding and processor connections stay in the app. **Scope:** `write` Parameters: - id (path, required): Prefixed id (`prg_…`) Body: ProgramUpdate ### GET /v1/partners List partners **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: group - include[] (query): Extras to include: stats, tags - status (query) - group_id (query) - email (query) - handle (query) - search (query) ### POST /v1/partners Create a partner Adds a partner directly (`status: active`) or into the review queue (`status: pending`). The handle is derived from the email when omitted. **Scope:** `partners:write` (or `write`) Body: PartnerCreate ### GET /v1/partners/{id} Retrieve a partner **Scope:** `read` Parameters: - id (path, required): Prefixed id (`part_…`) - expand[] (query): Relations to embed: group - include[] (query): Extras to include: stats, tags ### POST /v1/partners/{id} Update a partner **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`part_…`) Body: PartnerUpdate ### DELETE /v1/partners/{id} Delete a partner Removes the partner and everything attributed to them: links, referrals, customers, commissions, payouts. Not reversible. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`part_…`) ### POST /v1/partners/{id}/sso Mint a sign-in link A single-use magic link that signs the partner straight into their portal. Fifteen-minute life. Drop it into your own emails or app. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`part_…`) Body: - ttl_seconds (optional): integer ### GET /v1/groups List groups A group is the commission and approval axis: flows scope to it. Presentation and tags are separate, so one group never has to carry seven concerns. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): No relations on this resource - include[] (query): Extras to include: stats ### POST /v1/groups Create a group **Scope:** `partners:write` (or `write`) Body: GroupCreate ### GET /v1/groups/{id} Retrieve a group **Scope:** `read` Parameters: - id (path, required): Prefixed id (`grp_…`) - expand[] (query): No relations on this resource - include[] (query): Extras to include: stats ### POST /v1/groups/{id} Update a group `is_default: true` makes this the group new partners land in and clears the flag on the previous default. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`grp_…`) Body: GroupUpdate ### DELETE /v1/groups/{id} Delete a group Partners in it are left without a group; flows scoped to it are deleted with it. The default group cannot be deleted. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`grp_…`) ### GET /v1/tags List tags Tags are the free second axis: flows, campaigns, notifications and resources can all target them. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): No relations on this resource - include[] (query): Nothing to include on this resource ### POST /v1/tags Create a tag **Scope:** `partners:write` (or `write`) Body: TagCreate ### GET /v1/tags/{id} Retrieve a tag **Scope:** `read` Parameters: - id (path, required): Prefixed id (`tag_…`) ### POST /v1/tags/{id} Update a tag **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`tag_…`) Body: TagUpdate ### DELETE /v1/tags/{id} Delete a tag **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`tag_…`) ### GET /v1/applications List applications A real object with history: who applied, when, what they answered, who decided and why. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, group - include[] (query): Nothing to include on this resource - status (query) - partner_id (query) ### GET /v1/applications/{id} Retrieve an application **Scope:** `read` Parameters: - id (path, required): Prefixed id (`app_…`) - expand[] (query): Relations to embed: partner, group - include[] (query): Nothing to include on this resource ### POST /v1/applications/{id}/approve Approve an application The partner becomes active, the reviewer and time are recorded, `application.approved` and `affiliate.confirmed` fire, and the applicant gets the approval email with your overrides and sending domain. Refused when the application was already decided, or when your plan's revenue meter blocks new approvals. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`app_…`) ### POST /v1/applications/{id}/reject Reject an application The partner is declined and told why: your `reason` reaches them word for word, and a blank one falls back to the program's default sentence. `application.rejected` fires. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`app_…`) Body: ApplicationReject ### GET /v1/links List links **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner - include[] (query): Extras to include: stats - partner_id (query) ### POST /v1/links Create a link A destination plus a tracking value. The value defaults to the partner's handle; a custom value must be unique in the program. **Scope:** `partners:write` (or `write`) Body: LinkCreate ### GET /v1/links/{id} Retrieve a link **Scope:** `read` Parameters: - id (path, required): Prefixed id (`lnk_…`) - expand[] (query): Relations to embed: partner - include[] (query): Extras to include: stats ### POST /v1/links/{id} Update a link Changing the destination never rewrites the tracking value: published links keep working. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`lnk_…`) Body: LinkUpdate ### DELETE /v1/links/{id} Delete a link The link stops being listed and cannot be retrieved again. The URL itself keeps redirecting for anyone still holding it, and its click history stays grouped under it, because deleting a link a partner has already published would break a promise they made to their own audience. **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`lnk_…`) ### GET /v1/coupons List coupons Coupon codes are created by you in your payment processor and registered here so a checkout that used one is attributed to the partner. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, group - include[] (query): Extras to include: stats - partner_id (query) ### POST /v1/coupons Create a coupon **Scope:** `partners:write` (or `write`) Body: CouponCreate ### GET /v1/coupons/{id} Retrieve a coupon **Scope:** `read` Parameters: - id (path, required): Prefixed id (`cpn_…`) - expand[] (query): Relations to embed: partner, group - include[] (query): Extras to include: stats ### POST /v1/coupons/{id} Update a coupon **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`cpn_…`) Body: CouponUpdate ### DELETE /v1/coupons/{id} Delete a coupon **Scope:** `partners:write` (or `write`) Parameters: - id (path, required): Prefixed id (`cpn_…`) ### GET /v1/clicks List clicks **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, link, referral - include[] (query): Nothing to include on this resource - partner_id (query) - link_id (query) - referral_id (query) ### POST /v1/clicks Record a click Server-side tracking: the same resolution `rail.js` uses (handle first, then custom link values). An unknown value is a 404, not a silent drop. The same `visitor_token` across clicks joins one referral. **Scope:** `commissions:write` (or `write`) Body: ClickCreate ### GET /v1/clicks/{id} Retrieve a click **Scope:** `read` Parameters: - id (path, required): Prefixed id (`clk_…`) - expand[] (query): Relations to embed: partner, link, referral - include[] (query): Nothing to include on this resource ### GET /v1/referrals List referrals A referral is a unique visit, not a person. It moves `visit` -> `lead` -> `converted` and expires at `expires_at`, written from the program's cookie window at creation. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, link - include[] (query): Nothing to include on this resource - partner_id (query) - status (query) ### GET /v1/referrals/{id} Retrieve a referral **Scope:** `read` Parameters: - id (path, required): Prefixed id (`ref_…`) - expand[] (query): Relations to embed: partner, link - include[] (query): Nothing to include on this resource ### GET /v1/customers List customers Six explicit statuses, `refunded` included. The envelope is the same flat `{ data, has_more, total_count }` as every other list. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, referral, link - include[] (query): Nothing to include on this resource - partner_id (query) - status (query) - email (query) - external_customer_id (query) ### POST /v1/customers Create a customer Through a click (`click_id`, the referral's identity carries over and the partner is whoever owns it) or directly to a partner (`partner_id`, recorded as `tracked_by: api`). Set `external_customer_id` so charges you send later match. **Scope:** `commissions:write` (or `write`) Body: CustomerCreate ### GET /v1/customers/{id} Retrieve a customer **Scope:** `read` Parameters: - id (path, required): Prefixed id (`cus_…`) - expand[] (query): Relations to embed: partner, referral, link - include[] (query): Nothing to include on this resource ### POST /v1/customers/{id} Update a customer `partner_id` reassigns the customer; the change is recorded as manual attribution and shown to both partners. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`cus_…`) Body: CustomerUpdate ### DELETE /v1/customers/{id} Delete a customer Refused once the customer has sales: money that moved stays on the ledger. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`cus_…`) ### GET /v1/sales List sales **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, customer - include[] (query): Nothing to include on this resource - partner_id (query) - customer_id (query) - occurred_after (query) - occurred_before (query) - refunded (query) ### POST /v1/sales Record a sale Charge -> sale -> commission -> balance, atomically, through the same writer the processor webhooks use. Idempotent on `external_charge_id`: sending the same charge twice returns the same sale with a 200 instead of a 201. `amount_minor` is gross; tax is subtracted before the rate when the program commissions on net revenue. Customer auto-enrol runs on processor webhooks, not on this endpoint. **Scope:** `commissions:write` (or `write`) Body: SaleCreate ### GET /v1/sales/{id} Retrieve a sale **Scope:** `read` Parameters: - id (path, required): Prefixed id (`sale_…`) - expand[] (query): Relations to embed: partner, customer - include[] (query): Nothing to include on this resource ### POST /v1/sales/{id}/refund Refund a sale Voids the sale's unpaid commissions; an already-paid commission becomes a clawback against the partner's next balance. Replay-safe: refunding twice is a no-op. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`sale_…`) Body: - refunded_at (optional): string (date-time) - reason (optional): string ### GET /v1/commissions List commissions Every commission says which flow and which branch produced it. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, customer, sale, payout, flow - include[] (query): Nothing to include on this resource - partner_id (query) - status (query) - sale_id (query) - payout_id (query) - kind (query) ### POST /v1/commissions Create a manual commission A commission the engine did not produce: a bonus, or a missed referral attached to a sale. Approved on creation, held for the program's holding period, audited with your reason. **Scope:** `commissions:write` (or `write`) Body: CommissionCreate ### GET /v1/commissions/{id} Retrieve a commission **Scope:** `read` Parameters: - id (path, required): Prefixed id (`com_…`) - expand[] (query): Relations to embed: partner, customer, sale, payout, flow - include[] (query): Nothing to include on this resource ### POST /v1/commissions/{id}/approve Approve a commission `pending` -> `approved`, or straight to `due` when the holding period has already run. Anything else is refused with the reason. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`com_…`) Body: CommissionDecision ### POST /v1/commissions/{id}/reject Reject a commission Unpaid only. The reason is required and lands in the audit log and the partner's view. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`com_…`) Body: CommissionReject ### GET /v1/balances List balances One row per partner per currency: `pending_minor` (earned, inside the hold), `due_minor` (payable now), `paid_minor` (sent). Ordered by partner then currency; the cursor is a balance id. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner - include[] (query): Nothing to include on this resource - partner_id (query) - currency (query) ### GET /v1/balances/{id} Retrieve a balance **Scope:** `read` Parameters: - id (path, required) - expand[] (query): Relations to embed: partner - include[] (query): Nothing to include on this resource ### GET /v1/payouts List payouts `not_eligible` payouts carry the reason in words. Nothing is dropped silently. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner, batch - include[] (query): Nothing to include on this resource - partner_id (query) - batch_id (query) - status (query) ### GET /v1/payouts/{id} Retrieve a payout **Scope:** `read` Parameters: - id (path, required): Prefixed id (`pyt_…`) - expand[] (query): Relations to embed: partner, batch - include[] (query): Nothing to include on this resource ### POST /v1/payouts/{id}/mark_paid Mark a payout paid You paid it yourself, outside the connected rails. Moves the commissions to `paid` and the money from due to paid. Allowed from `pending` and `failed`; never while a rail has it in flight, never twice. **Scope:** `payouts:write` (or `write`) Parameters: - id (path, required): Prefixed id (`pyt_…`) Body: PayoutMarkPaid ### GET /v1/payout_batches List payout batches **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): No relations on this resource - include[] (query): Nothing to include on this resource ### POST /v1/payout_batches Generate a payout batch Turns every `due` commission up to `period_end` into payouts, one per partner per currency, netting clawbacks and applying the threshold, payout-method and tax-form checks. Idempotent per partner per month: a second run for the same month skips partners already paid and re-evaluates the not-eligible ones. Money does not move; this creates the payable set. **Scope:** `payouts:write` (or `write`) Body: PayoutBatchCreate ### GET /v1/payout_batches/{id} Retrieve a payout batch The payouts inside it are `GET /v1/payouts?batch_id=…`. **Scope:** `read` Parameters: - id (path, required): Prefixed id (`batch_…`) ### GET /v1/flows List flows Ordered by `priority` then specificity (partner beats group beats program-wide). Each flow carries its ordered `branches`; the first matching branch wins, falling back to the flow's own rate. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: group, partner - include[] (query): Nothing to include on this resource - status (query) - group_id (query) - partner_id (query) ### POST /v1/flows Create a flow Counts against the plan's flow quota. Scope to a group or a partner, not both. **Scope:** `commissions:write` (or `write`) Body: FlowCreate ### GET /v1/flows/{id} Retrieve a flow **Scope:** `read` Parameters: - id (path, required): Prefixed id (`flw_…`) - expand[] (query): Relations to embed: group, partner - include[] (query): Nothing to include on this resource ### POST /v1/flows/{id} Update a flow Send the whole flow. `branches` replaces the list: branches with an `id` are kept (and the commissions citing them keep pointing at them), the rest are created, omitted ones are deleted. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`flw_…`) Body: FlowUpdate ### DELETE /v1/flows/{id} Delete a flow Commissions it produced keep their `flow_id` for the audit trail. **Scope:** `commissions:write` (or `write`) Parameters: - id (path, required): Prefixed id (`flw_…`) ### GET /v1/reports Run a report Clicks, leads, customers, sales, refunds, revenue and commissions, cut by `dimension` over an inclusive range. Rows keyed `direct` are money that arrived without a partner; filtering by partner, group or tag reports that slice of the partner programme and excludes direct money. **Scope:** `read` Parameters: - program_id (query, required) - dimension (query) - from (query): ISO date, inclusive. Defaults to twelve months back. - to (query): ISO date, inclusive. Defaults to now. - partner_id (query) - group_id (query) - tag_id (query) - granularity (query): Bucket size for the period dimension ### GET /v1/risk_flags List risk flags Highest severity first, newest first within one. `evidence` carries what the check saw. New flags are created by the risk checks, which run on plans with fraud monitoring; history stays readable on every plan. **Scope:** `read` Parameters: - program_id (query, required) - status (query) - partner_id (query) - limit (query): 1 to 100, default 50 - offset (query) ### GET /v1/risk_flags/{id} Retrieve a risk flag **Scope:** `read` Parameters: - id (path, required) ### POST /v1/risk_flags/{id}/resolve Resolve a risk flag Closes the flag as `resolved` (acted on) or `dismissed` (false alarm). The note is required: it is the audit trail for why a fraud signal was waved through or acted on, and the change lands in the audit log naming your API key. **Scope:** `write` Parameters: - id (path, required) Body: RiskFlagResolve ### GET /v1/resources List resources Everything on the shelf, folders flattened onto each row. Empty `group_ids` and `tag_ids` mean every partner sees it. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): No relations on this resource - include[] (query): Nothing to include on this resource ### POST /v1/resources Create a link resource A link on the shelf, published straight away unless you say otherwise. File uploads happen in the dashboard. **Scope:** `write` Body: ResourceCreate ### GET /v1/resources/{id} Retrieve a resource **Scope:** `read` Parameters: - id (path, required): Prefixed id (`res_…`) ### POST /v1/resources/{id} Update a resource Title, folder, audience scoping and `published`; `url` on links only. Moving folders puts the resource at the end of the new one. **Scope:** `write` Parameters: - id (path, required): Prefixed id (`res_…`) Body: ResourceUpdate ### DELETE /v1/resources/{id} Delete a resource Files also lose their stored blob, best effort. **Scope:** `write` Parameters: - id (path, required): Prefixed id (`res_…`) ### GET /v1/campaigns List campaigns Newest first, with delivery stats. Drafts are composed in the dashboard. **Scope:** `read` Parameters: - program_id (query, required) ### GET /v1/campaigns/{id} Retrieve a campaign **Scope:** `read` Parameters: - id (path, required) - program_id (query, required) ### POST /v1/campaigns/{id}/send Send a campaign Sends a draft or paused campaign now, to the audience saved on it: the audience is queued atomically and the sender runs exactly as the dashboard's Send button. Refused when nobody matches the audience or the campaign is not sendable from its current state. **Scope:** `write` Parameters: - id (path, required) Body: CampaignSend ### GET /v1/sequences List sequences Every sequence with its trigger, step count and enrolment counts. **Scope:** `read` Parameters: - program_id (query, required) ### POST /v1/sequences/{id}/pause Pause a sequence Nobody is dropped: a paused sequence advances nobody, and resuming carries each partner on from the step they were on. **Scope:** `write` Parameters: - id (path, required) Body: SequenceAction ### POST /v1/sequences/{id}/resume Resume a sequence Turns a paused sequence back on. Each enrolled partner carries on from the step they were on. **Scope:** `write` Parameters: - id (path, required) Body: SequenceResume ### GET /v1/webhook_endpoints List webhook endpoints The event catalogue, payload examples and signature verification are published at https://app.affiliaterail.com/webhooks/llms.txt. **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): No relations on this resource - include[] (query): Nothing to include on this resource ### POST /v1/webhook_endpoints Create a webhook endpoint HTTPS, public address only. The response carries `secret` exactly once. **Scope:** `webhooks:write` (or `write`) Body: WebhookEndpointCreate ### GET /v1/webhook_endpoints/{id} Retrieve a webhook endpoint **Scope:** `read` Parameters: - id (path, required): Prefixed id (`whe_…`) ### POST /v1/webhook_endpoints/{id} Update a webhook endpoint **Scope:** `webhooks:write` (or `write`) Parameters: - id (path, required): Prefixed id (`whe_…`) Body: WebhookEndpointUpdate ### DELETE /v1/webhook_endpoints/{id} Delete a webhook endpoint **Scope:** `webhooks:write` (or `write`) Parameters: - id (path, required): Prefixed id (`whe_…`) ### POST /v1/webhook_endpoints/{id}/rotate_secret Rotate the signing secret Deliveries after this call are signed with the new secret, and with the old one as well for 24 hours (two `v1=` entries in `Rail-Signature`), so you can swap at your own pace. **Scope:** `webhooks:write` (or `write`) Parameters: - id (path, required): Prefixed id (`whe_…`) ### GET /v1/webhook_endpoints/{id}/deliveries Recent deliveries The last 50 attempts: status, attempt count, response code, and the exact body we sent. **Scope:** `read` Parameters: - id (path, required): Prefixed id (`whe_…`) ### GET /v1/webhook_events The event catalogue Every event type an endpoint can subscribe to, with a description and an example payload. **Scope:** `read` ### GET /v1/tax_form_statuses List tax-form statuses **Scope:** `read` Parameters: - program_id (query, required): Required on every list - limit (query): 1 to 100, default 25 - starting_after (query): Object id; returns the page after it (older) - ending_before (query): Object id; returns the page before it (newer) - expand[] (query): Relations to embed: partner - include[] (query): Nothing to include on this resource - partner_id (query) - status (query) ### GET /v1/tax_form_statuses/{id} Retrieve a tax-form status **Scope:** `read` Parameters: - id (path, required): Prefixed id (`tax_…`) - expand[] (query): Relations to embed: partner - include[] (query): Nothing to include on this resource ## Objects ### ProgramList - data (required): array of Program - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Program - id (required): string: Prefixed id (`prg_…`) - object (required): string one of "program" - name (required): string - product_name (required): string - website_url (required): string - currency (required): string: ISO-4217 - status (required): string one of "active", "paused" - subdomain (required): string - custom_domain (required, nullable): string - terms_url (required, nullable): string - terms_version (required, nullable): string - cookie_days (required): integer - url_params (required): array of string - commission_on_net_revenue (required): boolean - holding_period_days (required): integer - min_payout_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - payout_term (required): string one of "net_15", "net_30", "net_60" - payout_methods (required): array of string one of "paypal", "wise", "bank_transfer", "wire", "crypto" - block_self_referrals (required): boolean - blocked_countries (required): array of string - require_tax_forms (required): boolean - auto_payouts_enabled (required): boolean - processor (required, nullable): string one of "stripe", "paddle", "chargebee", "manual", "api", null - stats (optional): ProgramStats - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### ProgramStats - partners (required): integer - active_partners (required): integer - clicks (required): integer - referrals (required): integer - customers (required): integer - sales_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - commissions_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. ### Error - error (required): - type (required): string one of "authentication_error", "permission_error", "invalid_request_error", "not_found_error", "conflict_error", "rate_limit_error", "plan_error", "not_implemented_error", "api_error" - code (required): string - message (required): string - param (optional): string ### ProgramUpdate - name (optional): string - product_name (optional): string - website_url (optional): string (uri) - status (optional): string one of "active", "paused" - terms_url (optional, nullable): string (uri) - cookie_days (optional): integer - commission_on_net_revenue (optional): boolean - holding_period_days (optional): integer - min_payout_minor (optional): integer: Integer minor units (cents, pence). Never a float, never a string. - payout_term (optional): string one of "net_15", "net_30", "net_60" - block_self_referrals (optional): boolean - blocked_countries (optional): array of string - require_tax_forms (optional): boolean ### PartnerList - data (required): array of Partner - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Partner - id (required): string: Prefixed id (`part_…`) - object (required): string one of "partner" - program_id (required): string: Prefixed id (`prg_…`) - group_id (required, nullable): string: Prefixed id (`grp_…`) - email (required): string (email) - first_name (required, nullable): string - last_name (required, nullable): string - display_name (required, nullable): string - company_name (required, nullable): string - website_url (required, nullable): string - country_code (required, nullable): string - language_code (required, nullable): string - handle (required): string: The `?ref=` value - status (required): string one of "pending", "active", "declined", "suspended" - decline_reason (required, nullable): string - suspension_reason (required, nullable): string - min_payout_minor (required, nullable): integer: Per-partner threshold override; null means the program's - terms_accepted_at (required, nullable): string (date-time): ISO-8601, UTC - terms_version (required, nullable): string - completed_onboarding (required): boolean - email_first_referral (required): boolean - email_new_referral (required): boolean - email_payout_paid (required): boolean - metadata (required, nullable): object: Your own key/value data, stored as given - stats (optional): PartnerStats - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### PartnerStats - clicks (required): integer - referrals (required): integer - customers (required): integer - commissions_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - paid_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. ### PartnerCreate - program_id (required): string: Prefixed id (`prg_…`) - email (required): string (email) - first_name (optional): string - last_name (optional): string - company_name (optional): string - website_url (optional): string (uri) - country_code (optional): string - handle (optional): string: 2 to 32 chars, letters, digits, hyphens. Derived from the email when omitted. - group_id (optional): string: Prefixed id (`grp_…`) - status (optional): string one of "active", "pending": `pending` puts the partner in the review queue instead of activating them - metadata (optional, nullable): object: Your own key/value data, stored as given ### PartnerUpdate - first_name (optional, nullable): string - last_name (optional, nullable): string - display_name (optional, nullable): string - company_name (optional, nullable): string - website_url (optional, nullable): string (uri) - country_code (optional, nullable): string - handle (optional): string - group_id (optional, nullable): string: Prefixed id (`grp_…`) - min_payout_minor (optional, nullable): integer: Integer minor units (cents, pence). Never a float, never a string. - status (optional): string one of "active", "suspended": Suspend or reinstate. Approval of a pending partner goes through applications. - suspension_reason (optional, nullable): string - tag_ids (optional): array of string: Replaces the partner's tags - metadata (optional, nullable): object: Your own key/value data, stored as given ### Deleted - id (required): string: Prefixed id (`part_…`) - object (required): string - deleted (required): boolean one of true ### MagicLink - object (required): string one of "magic_link" - partner_id (required): string: Prefixed id (`part_…`) - url (required): string (uri) - expires_at (required): string (date-time): ISO-8601, UTC ### GroupList - data (required): array of Group - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Group - id (required): string: Prefixed id (`grp_…`) - object (required): string one of "group" - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - slug (required): string - description (required, nullable): string - landing_url (required, nullable): string - is_private (required): boolean - is_default (required): boolean - stats (optional): - partners (required): integer - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### GroupCreate - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - description (optional): string - landing_url (optional): string (uri) - is_private (optional): boolean ### GroupUpdate - name (optional): string - description (optional, nullable): string - landing_url (optional, nullable): string (uri) - is_private (optional): boolean - is_default (optional): boolean one of true ### TagList - data (required): array of Tag - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Tag - id (required): string: Prefixed id (`tag_…`) - object (required): string one of "tag" - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - color (required): string - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### TagCreate - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - color (optional): string ### TagUpdate - name (optional): string - color (optional): string ### ApplicationList - data (required): array of Application - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Application - id (required): string: Prefixed id (`app_…`) - object (required): string one of "application" - program_id (required): string: Prefixed id (`prg_…`) - group_id (required, nullable): string: Prefixed id (`grp_…`) - partner_id (required, nullable): string: Prefixed id (`part_…`) - email (required): string - answers (optional): any - source (required, nullable): string - status (required): string one of "pending", "approved", "rejected", "withdrawn" - reviewed_by_user_id (required, nullable): string - reviewed_at (required, nullable): string (date-time): ISO-8601, UTC - rejection_reason (required, nullable): string - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### ApplicationReject - reason (optional): string: Shown to the applicant word for word. Blank falls back to the program's default sentence. ### LinkList - data (required): array of Link - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Link - id (required): string: Prefixed id (`lnk_…`) - object (required): string one of "link" - partner_id (required): string: Prefixed id (`part_…`) - param (required): string - value (required): string - destination_url (required): string - url (required): string: The destination with the tracking parameter applied - short_url (required, nullable): string - short_slug (required, nullable): string - short_domain (required, nullable): string - label (required, nullable): string - rate_override (optional): any - stats (optional): - clicks (required): integer - referrals (required): integer - customers (required): integer - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### LinkCreate - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - destination_url (required): string (uri) - value (optional): string: The tracking value; defaults to the partner's handle - param (optional): string - label (optional): string ### LinkUpdate - destination_url (optional): string (uri) - label (optional, nullable): string ### CouponList - data (required): array of Coupon - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Coupon - id (required): string: Prefixed id (`cpn_…`) - object (required): string one of "coupon" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required, nullable): string: Prefixed id (`part_…`) - group_id (required, nullable): string: Prefixed id (`grp_…`) - code (required): string - external_id (required, nullable): string: The processor's own promotion id, and the only thing a sale is matched on - stats (optional): - customers (required): integer - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### CouponCreate - program_id (required): string: Prefixed id (`prg_…`) - code (required): string - partner_id (optional): string: Prefixed id (`part_…`) - group_id (optional): string: Prefixed id (`grp_…`) - external_id (optional): string ### CouponUpdate - external_id (optional, nullable): string - partner_id (optional, nullable): string: Prefixed id (`part_…`) ### ClickList - data (required): array of Click - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Click - id (required): string: Prefixed id (`clk_…`) - object (required): string one of "click" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - link_id (required, nullable): string: Prefixed id (`lnk_…`) - referral_id (required, nullable): string: Prefixed id (`ref_…`) - user_agent (required, nullable): string - referer (required, nullable): string - country (required, nullable): string - device (required, nullable): string - landing_url (required, nullable): string - created_at (required): string (date-time): ISO-8601, UTC ### ClickCreate - program_id (required): string: Prefixed id (`prg_…`) - value (required): string: The partner handle or link value the visitor arrived with - param (optional): string - landing_url (required): string (uri) - visitor_token (required): string: Your stable identifier for this visitor; the same token across clicks makes one referral - referrer (optional): string - ip (optional): string: Hashed on write, never stored - user_agent (optional): string - country (optional): string - device (optional): string ### ReferralList - data (required): array of Referral - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Referral - id (required): string: Prefixed id (`ref_…`) - object (required): string one of "referral" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - link_id (required, nullable): string: Prefixed id (`lnk_…`) - landing_url (required, nullable): string - utm (optional): any - tracked_by (required): string one of "link", "coupon", "manual", "api" - status (required): string one of "visit", "lead", "converted" - expires_at (required): string (date-time): ISO-8601, UTC - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### CustomerList - data (required): array of Customer - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Customer - id (required): string: Prefixed id (`cus_…`) - object (required): string one of "customer" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - referral_id (required, nullable): string: Prefixed id (`ref_…`) - link_id (required, nullable): string: Prefixed id (`lnk_…`) - coupon_id (required, nullable): string: Prefixed id (`cpn_…`) - processor (required, nullable): string one of "stripe", "paddle", "chargebee", "manual", "api", null - external_customer_id (required, nullable): string - external_subscription_id (required, nullable): string - email (required, nullable): string - name (required, nullable): string - identifier (required, nullable): string - status (required): string one of "lead", "trial", "active", "cancelled", "refunded", "suspended" - tracked_by (required): string one of "link", "coupon", "manual", "api" - lead_at (required, nullable): string (date-time): ISO-8601, UTC - converted_at (required, nullable): string (date-time): ISO-8601, UTC - metadata (required, nullable): object: Your own key/value data, stored as given - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### CustomerCreate - program_id (required): string: Prefixed id (`prg_…`) - partner_id (optional): string: Attribute directly to a partner - click_id (optional): string: Or attribute through the click the visitor arrived on (one of partner_id or click_id is required) - email (optional): string (email) - name (optional): string - identifier (optional): string: Your own id for this customer - external_customer_id (optional): string: The processor's customer id, used to match incoming charges - status (optional): string one of "lead", "trial", "active", "cancelled", "suspended" - metadata (optional, nullable): object: Your own key/value data, stored as given ### CustomerUpdate - email (optional, nullable): string (email) - name (optional, nullable): string - identifier (optional, nullable): string - status (optional): string one of "lead", "trial", "active", "cancelled", "suspended": `refunded` is written by the refund itself - partner_id (optional): string: Reassign; recorded as manual attribution - metadata (optional, nullable): object: Your own key/value data, stored as given ### SaleList - data (required): array of Sale - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Sale - id (required): string: Prefixed id (`sale_…`) - object (required): string one of "sale" - program_id (required): string: Prefixed id (`prg_…`) - customer_id (required): string: Prefixed id (`cus_…`) - partner_id (required): string: Prefixed id (`part_…`) - external_charge_id (required): string - external_payment_intent_id (required, nullable): string - processor (required): string one of "stripe", "paddle", "chargebee", "manual", "api" - amount_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - tax_minor (required, nullable): integer: Integer minor units (cents, pence). Never a float, never a string. - currency (required): string: ISO-4217 - billing_type (required): string one of "one_time", "subscription" - interval (required, nullable): string one of "day", "week", "month", "year", null - product_id (required, nullable): string - product_name (required, nullable): string - is_first_sale (required): boolean - occurred_at (required): string (date-time): ISO-8601, UTC - refunded_at (required, nullable): string (date-time): ISO-8601, UTC - metadata (required, nullable): object: Your own key/value data, stored as given - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### SaleCreate - program_id (required): string: Prefixed id (`prg_…`) - customer_id (required): string: Prefixed id (`cus_…`) - external_charge_id (required): string: Your charge id. One charge produces at most one sale, forever. - amount_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - tax_minor (optional, nullable): integer: Integer minor units (cents, pence). Never a float, never a string. - currency (required): string: ISO-4217 - billing_type (optional): string one of "one_time", "subscription" - interval (optional, nullable): string one of "day", "week", "month", "year", null - product_id (optional, nullable): string - product_name (optional, nullable): string - occurred_at (optional): string (date-time): ISO-8601, UTC - metadata (optional, nullable): object: Your own key/value data, stored as given ### RefundResult - object (required): string one of "refund" - sale_id (required): string: Prefixed id (`sale_…`) - voided_commissions (required): integer - clawback_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - refunded_at (required): string (date-time): ISO-8601, UTC ### CommissionList - data (required): array of Commission - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Commission - id (required): string: Prefixed id (`com_…`) - object (required): string one of "commission" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - sale_id (required, nullable): string: Prefixed id (`sale_…`) - customer_id (required, nullable): string: Prefixed id (`cus_…`) - flow_id (required, nullable): string: Which flow produced it - flow_branch_id (required, nullable): string: And which branch - kind (required): string one of "referral", "reward", "clawback" - amount_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - revenue_minor (required, nullable): integer: Integer minor units (cents, pence). Never a float, never a string. - currency (required): string: ISO-4217 - status (required): string one of "pending", "approved", "due", "paid", "rejected", "voided" - mature_at (required, nullable): string (date-time): ISO-8601, UTC - approved_at (required, nullable): string (date-time): ISO-8601, UTC - voided_at (required, nullable): string (date-time): ISO-8601, UTC - void_reason (required, nullable): string - payout_id (required, nullable): string: Prefixed id (`pyt_…`) - metadata (required, nullable): object: Your own key/value data, stored as given - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### CommissionCreate - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - amount_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - currency (optional): string: ISO-4217 - customer_id (optional): string: Prefixed id (`cus_…`) - sale_id (optional): string: Prefixed id (`sale_…`) - reason (required): string: Why this commission exists; written to the audit log ### CommissionDecision - reason (optional): string ### CommissionReject - reason (required): string ### BalanceList - data (required): array of Balance - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Balance - id (required): string: `bal__` - object (required): string one of "balance" - partner_id (required): string: Prefixed id (`part_…`) - currency (required): string: ISO-4217 - pending_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - due_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - paid_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - updated_at (required): string (date-time): ISO-8601, UTC ### PayoutList - data (required): array of Payout - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Payout - id (required): string: Prefixed id (`pyt_…`) - object (required): string one of "payout" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required): string: Prefixed id (`part_…`) - batch_id (required, nullable): string: Prefixed id (`batch_…`) - amount_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - currency (required): string: ISO-4217 - method (required, nullable): string one of "paypal", "wise", "bank_transfer", "wire", "crypto", null - status (required): string one of "not_eligible", "pending", "processing", "paid", "failed" - not_eligible_reason (required, nullable): string: Why this partner was not paid this period, in words - external_id (required, nullable): string - error_code (required, nullable): string - error_message (required, nullable): string - period_start (required, nullable): string (date-time): ISO-8601, UTC - period_end (required, nullable): string (date-time): ISO-8601, UTC - paid_at (required, nullable): string (date-time): ISO-8601, UTC - metadata (required, nullable): object: Your own key/value data, stored as given - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### PayoutMarkPaid - paid_at (optional): string (date-time): ISO-8601, UTC - external_id (optional): string: Your reference from the rail you paid through ### PayoutBatchList - data (required): array of PayoutBatch - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### PayoutBatch - id (required): string: Prefixed id (`batch_…`) - object (required): string one of "payout_batch" - program_id (required): string: Prefixed id (`prg_…`) - term (required): string one of "net_15", "net_30", "net_60" - period_start (required): string (date-time): ISO-8601, UTC - period_end (required): string (date-time): ISO-8601, UTC - currency (required): string: ISO-4217 - total_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - payout_count (required): integer - generated_by_user_id (required, nullable): string - executed_at (required, nullable): string (date-time): ISO-8601, UTC - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### PayoutBatchRun - object (required): string one of "payout_batch_run" - batches (required): array of PayoutBatch - created (required): array of - payout_id (required): string: Prefixed id (`pyt_…`) - partner_id (required): string: Prefixed id (`part_…`) - currency (required): string: ISO-4217 - amount_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - status (required): string one of "pending", "not_eligible" - reason (required, nullable): string - upgraded (required): array of string - refreshed (required): array of string - skipped (required): array of - partner_id (required): string: Prefixed id (`part_…`) - currency (required): string: ISO-4217 - status (required): string ### PayoutBatchCreate - program_id (required): string: Prefixed id (`prg_…`) - period_end (required): string (date-time): Last instant of the earning period - period_start (optional): string (date-time): ISO-8601, UTC - partner_ids (optional): array of string - group_id (optional): string: Prefixed id (`grp_…`) - ignore_threshold (optional): boolean ### FlowList - data (required): array of Flow - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Flow - id (required): string: Prefixed id (`flw_…`) - object (required): string one of "flow" - program_id (required): string: Prefixed id (`prg_…`) - group_id (required, nullable): string: Prefixed id (`grp_…`) - partner_id (required, nullable): string: Prefixed id (`part_…`) - name (required): string - description (required, nullable): string - trigger (required): string one of "new_payment", "new_signup" - action (required): string one of "generate_commission", "switch_group" - rate_type (required): string one of "percent", "fixed" - rate_value (required): integer: Basis points for percent, minor units for fixed. The fallback when no branch matches. - approval_mode (required): string one of "immediate", "after_days", "manual" - approval_delay_days (required, nullable): integer - priority (required): integer: Lower runs first - status (required): string one of "active", "inactive" - switch_to_group_id (required, nullable): string: Prefixed id (`grp_…`) - metadata (required, nullable): object: Your own key/value data, stored as given - branches (required): array of FlowBranch - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### FlowBranch - id (required): string: Prefixed id (`flb_…`) - object (required): string one of "flow_branch" - flow_id (required): string: Prefixed id (`flw_…`) - position (required): integer - label (required, nullable): string - conditions (required): Condition - rate_type (required): string one of "percent", "fixed" - rate_value (required): integer - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### Condition - field (required): string - op (required): string one of "eq", "neq", "gt", "gte", "lt", "lte", "between", "in", "not_in", "contains", "starts_with", "is_true", "is_false" - value (optional): any | - all (required): array of Condition | - any (required): array of Condition | - not (required): Condition ### FlowCreate - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - description (optional, nullable): string - group_id (optional, nullable): string: Prefixed id (`grp_…`) - partner_id (optional, nullable): string: Prefixed id (`part_…`) - trigger (optional): string one of "new_payment", "new_signup" - action (optional): string one of "generate_commission", "switch_group" - rate_type (optional): string one of "percent", "fixed" - rate_value (optional): integer - approval_mode (optional): string one of "immediate", "after_days", "manual" - approval_delay_days (optional, nullable): integer - priority (optional): integer - status (optional): string one of "active", "inactive" - branches (optional): array of - id (optional): string: Prefixed id (`flb_…`) - label (optional, nullable): string - conditions (required): Condition - rate_type (required): string one of "percent", "fixed" - rate_value (required): integer ### FlowUpdate - name (optional): string - description (optional, nullable): string - group_id (optional, nullable): string: Prefixed id (`grp_…`) - partner_id (optional, nullable): string: Prefixed id (`part_…`) - trigger (optional): string one of "new_payment", "new_signup" - action (optional): string one of "generate_commission", "switch_group" - rate_type (optional): string one of "percent", "fixed" - rate_value (optional): integer - approval_mode (optional): string one of "immediate", "after_days", "manual" - approval_delay_days (optional, nullable): integer - priority (optional): integer - status (optional): string one of "active", "inactive" - branches (optional): array of - id (optional): string: Prefixed id (`flb_…`) - label (optional, nullable): string - conditions (required): Condition - rate_type (required): string one of "percent", "fixed" - rate_value (required): integer ### Report - object (required): string one of "report" - dimension (required): string one of "partner", "link", "product", "group", "tag", "period" - currency (required): string: ISO-4217 - from (required): string (date-time): ISO-8601, UTC - to (required): string (date-time): ISO-8601, UTC - rows (required): array of ReportRow - totals (required): any ### ReportRow - key (required, nullable): string: The grouping value: an id, a product name, an ISO day, or `direct`. Null is "none". - label (required): string - clicks (required, nullable): integer - leads (required, nullable): integer - customers (required): integer - sales (required): integer - refunded (required): integer - revenue_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - commissions_minor (required): integer: Integer minor units (cents, pence). Never a float, never a string. - conversion_bps (required, nullable): integer: customers / clicks in basis points; null with no clicks - refund_bps (required, nullable): integer ### RiskFlagList - data (required): array of RiskFlag - has_more (required): boolean - total_count (required): integer ### RiskFlag - id (required): string: Prefixed id (`rsk_…`) - object (required): string one of "risk_flag" - kind (required): string - severity (required): string one of "high", "medium", "low" - status (required): string one of "open", "reviewing", "resolved", "dismissed" - evidence (required): object: What the check saw: rates, ids, windows - partner (required, nullable): object - customer (required, nullable): object - resolved_at (required, nullable): string (date-time): ISO-8601, UTC - resolved_by (required, nullable): string - resolution_note (required, nullable): string - created_at (required): string (date-time): ISO-8601, UTC ### RiskFlagResolve - status (optional): string one of "resolved", "dismissed": `dismissed` closes it as a false alarm - note (required): string: What you found; required, and written to the audit log ### ResourceList - data (required): array of Resource - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### Resource - id (required): string: Prefixed id (`res_…`) - object (required): string one of "resource" - program_id (required): string: Prefixed id (`prg_…`) - kind (required): string one of "file", "link" - title (required): string - url (required): string - folder (required, nullable): string - mime_type (required, nullable): string - size_bytes (required, nullable): integer - group_ids (required): array of string: Empty means every group sees it - tag_ids (required): array of string - position (required): integer - published (required): boolean - published_at (required, nullable): string (date-time): ISO-8601, UTC - metadata (required, nullable): object: Your own key/value data, stored as given - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### ResourceCreate - program_id (required): string: Prefixed id (`prg_…`) - title (required): string - url (required): string (uri): Where the link points. File uploads happen in the dashboard; the API manages links and existing files. - folder (optional, nullable): string - group_ids (optional): array of string - tag_ids (optional): array of string - published (optional): boolean ### ResourceUpdate - title (optional): string - url (optional): string (uri): Links only; a file's URL is its blob - folder (optional, nullable): string - group_ids (optional): array of string - tag_ids (optional): array of string - published (optional): boolean ### CampaignList - data (required): array of Campaign - has_more (required): boolean - total_count (required): integer ### Campaign - id (required): string: Prefixed id (`camp_…`) - object (required): string one of "campaign" - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - subject (required): string - status (required): string one of "draft", "scheduled", "sending", "paused", "sent" - scheduled_at (required, nullable): string (date-time): ISO-8601, UTC - sent_at (required, nullable): string (date-time): ISO-8601, UTC - stats (required): - total (required): integer - queued (required): integer - sent (required): integer - failed (required): integer - opened (required): integer - skipped (required): integer - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### CampaignSend - program_id (required): string ### SequenceList - data (required): array of Sequence - has_more (required): boolean - total_count (required): integer ### Sequence - id (required): string: Prefixed id (`seq_…`) - object (required): string one of "sequence" - program_id (required): string: Prefixed id (`prg_…`) - name (required): string - status (required): string one of "active", "paused" - trigger (required): string one of "approved", "idle", "first_commission" - trigger_days (required, nullable): integer - steps (required): integer - counts (required): - enrolled (required): integer - active (required): integer - completed (required): integer - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### SequenceAction - program_id (required): string ### SequenceResume - program_id (required): string ### WebhookEndpointList - data (required): array of WebhookEndpoint - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### WebhookEndpoint - id (required): string: Prefixed id (`whe_…`) - object (required): string one of "webhook_endpoint" - program_id (required): string: Prefixed id (`prg_…`) - partner_id (required, nullable): string: Prefixed id (`part_…`) - url (required): string - event_types (required): array of string - enabled (required): boolean - secret (optional): string: Shown once, on creation - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC ### WebhookEndpointCreate - program_id (required): string: Prefixed id (`prg_…`) - url (required): string (uri) - event_types (optional): array of string: Empty means every event ### WebhookEndpointUpdate - url (optional): string (uri) - event_types (optional): array of string - enabled (optional): boolean ### TaxFormStatusList - data (required): array of TaxFormStatus - has_more (required): boolean: Pass the last object's id as `starting_after` to fetch the next page - total_count (required): integer: Count of every object matching the filters, ignoring the cursor ### TaxFormStatus - id (required): string: Prefixed id (`tax_…`) - object (required): string one of "tax_form_status" - partner_id (required): string: Prefixed id (`part_…`) - type (required): string one of "w9", "w8ben", "w8bene" - status (required): string one of "not_required", "required", "submitted", "expired", "superseded" - entity_type (required, nullable): string - country_code (required, nullable): string - signed_at (required, nullable): string (date-time): ISO-8601, UTC - expires_at (required, nullable): string (date-time): ISO-8601, UTC - created_at (required): string (date-time): ISO-8601, UTC - updated_at (required): string (date-time): ISO-8601, UTC