Every endpoint of the ViralPayouts REST API: 45 for brand keys and 21 for partner keys. Each is also an MCP tool, named on its card. This page and the OpenAPI document are generated from the same source. How keys, errors, pagination and idempotency work is in the overview.
Account
Check a key: which brand it acts for and its role.
{
"data": [
{
"id": "prg_9f2c1a",
"name": "Acme Pro",
"slug": "acme-pro",
"status": "live",
"currency": "USD",
"openToAll": false,
"commission": "25% of each sale",
"recruiterOverride": "10% of the commission of partners they recruit",
"holdDays": 30,
"attributionWindowDays": 30,
"renewals": "Every renewal, for the life of the subscription",
"minimumPayout": 10,
"newCustomersOnly": true,
"countries": [],
"termsVersion": 1,
"scheduledChange": null,
"applicationPage": "https://viralpayouts.com/apply/prg_9f2c1a"
}
],
"has_more": false,
"next_cursor": null
}
POST/api/v1/programs
Create a program
Creates a program as a draft. Needs a name and a destinationUrl; everything else takes the program terms defaults. Commission and the other terms must stay inside the program terms limits.
Brand key, owner role or higherMCP tool: create_programcreateProgram
Field
In
Type
Required
Description
name
body
string
Yes
The program name partners see. up to 120 chars
destinationUrl
body
string
Yes
Where partner links send visitors: the brand's site, https on mainnet.
description
body
string
No
up to 4000 chars
currency
body
string
No
Three-letter currency code. Default USD.
commissionPercent
body
number
No
Commission as a percent of each sale, 1 to 95. Use this or commissionFixed. min 1, max 95
commissionFixed
body
number
No
A flat fee per approved customer, in the program currency (e.g. 30 for $30). Use this or commissionPercent. min 1
recruiterOverridePercent
body
number
No
What a partner's recruiter earns, as a percent of that partner's commission: 0 for none (the default), or 1 to 95. min 0, max 95
holdDays
body
integer
No
Payment schedule: partners are paid this many days after the sale (the refund window), 15 to 30 on mainnet. Default 15. min 0, max 30
attributionWindowDays
body
integer
No
Cookie window: how long after a click a sale still counts, 7 to 365 days. Default 30. min 7, max 365
renewalMonths
body
integer or string: lifetime
No
Renewals that earn commission: 1 for the first payment only (a one-off fee), 2 to 36 months, or "lifetime" (the default).
minimumPayout
body
number
No
The balance a partner must reach before they are paid, in the program currency: 10 to 100 on mainnet. Default 10. min 0, max 100
newCustomersOnly
body
boolean
No
True (the default): only customers new to the brand earn a commission.
countries
body
array of string
No
Two-letter country codes the program is open to. Empty for every country (the default).
trafficRules
body
object
No
How partners may promote: allowed, ask (ask first) or banned, per source. Only the sources sent change.
brandRules
body
string
No
Up to 300 words of the brand's own rules for partners. ViralPayouts reviews them before partners see them. up to 2400 chars
attribution
body
string: last, first
No
Who is credited when a buyer followed several partners' links. Default last.
openToAll
body
boolean
No
True: anyone who applies is approved at once. False (default): the brand reviews each application.
status
body
string: draft, live, paused
No
draft (default) until you are ready; live lets partners join and earn.
Idempotency-Key
header
string
No
A unique value per request; a retry with the same value is answered once.
{
"data": {
"id": "prg_9f2c1a",
"name": "Acme Pro",
"slug": "acme-pro",
"status": "live",
"currency": "USD",
"openToAll": false,
"commission": "25% of each sale",
"recruiterOverride": "10% of the commission of partners they recruit",
"holdDays": 30,
"attributionWindowDays": 30,
"renewals": "Every renewal, for the life of the subscription",
"minimumPayout": 10,
"newCustomersOnly": true,
"countries": [],
"termsVersion": 1,
"scheduledChange": null,
"applicationPage": "https://viralpayouts.com/apply/prg_9f2c1a",
"rewardType": "percent",
"directRateBps": 2500,
"directFixedCents": 0,
"overrideBase": "commission",
"overrideRateBps": 1000,
"rateRules": {
"products": [],
"events": []
}
}
}
PATCH/api/v1/programs/{programId}
Update a program
Changes only the fields sent. On a live program with approved partners, a cut takes effect 3 business days later (see scheduledChange) and an increase applies at once; partners are emailed either way. A program with no partners changes at once.
Brand key, owner role or higherMCP tool: update_programupdateProgram
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
name
body
string
No
The program name partners see. up to 120 chars
destinationUrl
body
string
No
Where partner links send visitors: the brand's site, https on mainnet.
description
body
string
No
up to 4000 chars
currency
body
string
No
Three-letter currency code. Default USD.
commissionPercent
body
number
No
Commission as a percent of each sale, 1 to 95. Use this or commissionFixed. min 1, max 95
commissionFixed
body
number
No
A flat fee per approved customer, in the program currency (e.g. 30 for $30). Use this or commissionPercent. min 1
recruiterOverridePercent
body
number
No
What a partner's recruiter earns, as a percent of that partner's commission: 0 for none (the default), or 1 to 95. min 0, max 95
holdDays
body
integer
No
Payment schedule: partners are paid this many days after the sale (the refund window), 15 to 30 on mainnet. Default 15. min 0, max 30
attributionWindowDays
body
integer
No
Cookie window: how long after a click a sale still counts, 7 to 365 days. Default 30. min 7, max 365
renewalMonths
body
integer or string: lifetime
No
Renewals that earn commission: 1 for the first payment only (a one-off fee), 2 to 36 months, or "lifetime" (the default).
minimumPayout
body
number
No
The balance a partner must reach before they are paid, in the program currency: 10 to 100 on mainnet. Default 10. min 0, max 100
newCustomersOnly
body
boolean
No
True (the default): only customers new to the brand earn a commission.
countries
body
array of string
No
Two-letter country codes the program is open to. Empty for every country (the default).
trafficRules
body
object
No
How partners may promote: allowed, ask (ask first) or banned, per source. Only the sources sent change.
brandRules
body
string
No
Up to 300 words of the brand's own rules for partners. ViralPayouts reviews them before partners see them. up to 2400 chars
attribution
body
string: last, first
No
Who is credited when a buyer followed several partners' links. Default last.
openToAll
body
boolean
No
True: anyone who applies is approved at once. False (default): the brand reviews each application.
status
body
string: draft, live, paused
No
draft (default) until you are ready; live lets partners join and earn.
The partners of one program, newest first, with status, contact, clicks, customers, recruits, payout readiness and balance (cents). For results over a period use the stats endpoint.
Brand key, viewer role or higherMCP tool: browse_partnersPaginatedlistPartners
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
status
query
string: pending, approved, suspended, rejected
No
Only partners with this status.
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
A payment schedule agreed with this one partner: they are paid this many days after each sale (0 to 30) instead of the program's. null goes back to the program's. Commission rates are set per program and per product, not per partner.
Brand key, owner role or higherMCP tool: set_partner_payment_scheduleupdatePartner
Field
In
Type
Required
Description
partnerId
path
string
Yes
The partner id (prt_...): one person in one program.
holdDays
body
integer or null
Yes
Days after the sale, 0 to 30, or null for the program's schedule. min 0, max 30
Clicks, sales, sales value and commission grouped by the visitor's country or device. A sale with no click (coupon or referral code) is grouped as not known.
Brand key, viewer role or higherMCP tool: get_program_breakdowngetProgramBreakdown
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
by
query
string: country, device
No
Group by country (default) or device.
days
query
integer: 7, 30, 90, 365, 0
No
Period in days: 7, 30, 90 or 365, or 0 for all time. Default 30.
Counted clicks on the program's partner links, newest first: partner, country, device, referrer, landing page and sub IDs. Bots, previews and repeats are filtered out before they are counted.
Brand key, viewer role or higherMCP tool: list_clicksPaginatedlistClicks
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
partnerId
query
string
No
Only this partner's clicks. up to 120 chars
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
Rejects a conversion and reverses its commission, override and fee. Needs a reason the partner sees, or a reasonCode. Once a commission is past its payment date it can only be rejected with reasonCode fraud.
Brand key, manager role or higherMCP tool: decide_conversionrejectConversion
refund: The customer was refunded; chargeback: The payment was charged back or disputed; not_valid: The customer did not meet the valid customer rule; duplicate: The sale was a duplicate or a test order; self_or_employee: The customer was the partner, someone in their household, or the brand's employee; banned_source: The sale came from a banned source or banned conduct; leaked_code: The coupon code was posted on a leak or deal site without permission; fraud: The sale was fraudulent
Request
curl -X POST https://viralpayouts.com/api/v1/conversions/cnv_0c88aa/reject \
-H "Authorization: Bearer vpk_..." \
-H "Content-Type: application/json" \
-d '{"reason":"Brand bidding on our name"}'
Records a refund of the order behind a conversion, exactly as a refund event from the signed event API: commission, override and fee are reversed in proportion. Send amountCents (this refund) or refundedTotalCents (everything refunded so far). Leave both out for a full refund. A refund after the partner was paid is recovered from their next commissions. Needs an Idempotency-Key.
Brand key, owner role or higherMCP tool: refund_conversionIdempotency-Key requiredrefundConversion
Field
In
Type
Required
Description
conversionId
path
string
Yes
The conversion id (cnv_...).
amountCents
body
integer
No
The amount of this refund, in cents. min 1
refundedTotalCents
body
integer
No
The total refunded on the order so far, in cents. min 0
Idempotency-Key
header
string
Yes
A unique value per request; a retry with the same value is answered once.
Runs a test sale through the real pipeline for one partner (the first approved one if none is named). It is marked as a test and never becomes payable.
Brand key, manager role or higherMCP tool: send_test_salecreateTestSale
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
partnerId
body
string
No
A partner of this program. Optional. up to 120 chars
amount
body
number
No
Sale amount in the program currency (major units, 100 = $100). Default 100. min 0.01, max 1000000
Idempotency-Key
header
string
No
A unique value per request; a retry with the same value is answered once.
Every money entry of the program, newest first. The ledger is append-only: a correction is a new entry with the opposite sign. kind is direct (commission), override (recruiter) or platform_fee; entry is accrual, reversal, payout or payout_reversal. Cents.
Brand key, viewer role or higherMCP tool: list_ledgerPaginatedlistLedger
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
partnerId
query
string
No
Only this partner's entries. up to 120 chars
kind
query
string: direct, override, platform_fee
No
Only this kind.
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
Per partner: pending (awaiting approval), in hold (approved, before its payment date), payable, being paid, paid, and earned this year. Cents; test sales left out.
Brand key, viewer role or higherMCP tool: list_balanceslistBalances
What partners earn on this program: the commission, the recruiter override (the second tier) with its base and period, and any product rates and app-event bounties.
Brand key, viewer role or higherMCP tool: get_ratesgetRates
Replaces the program's product rates (a different commission for a product_id or plan) and app-event bounties (a fixed amount per signup, install...). On a live program with approved partners a cut takes effect 3 business days later (scheduledFor in the answer) and an increase at once; every partner is emailed either way. A change starts a new terms version when it applies. The program's own commission and recruiter override are changed with PATCH /programs/{programId}.
Brand key, owner role or higherMCP tool: set_rate_rulessetRateRules
Every partner of the program who recruited someone: how many recruits (and how many approved), and the recruiter override they earned on recruits' sales in the period, approved and pending (cents, after refunds). Test sales are left out.
Brand key, viewer role or higherMCP tool: list_recruiter_overrideslistRecruiterOverrides
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
days
query
integer: 7, 30, 90, 365, 0
No
Period in days: 7, 30, 90 or 365, or 0 for all time. Default 30.
Payout runs of the program, newest first, each with its total and what happened to its payouts: sent, sending, needing attention, by bank transfer or held.
Brand key, viewer role or higherMCP tool: list_payout_batchesPaginatedlistPayoutBatches
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
The sale and refund events this program received (event API, Stripe, Shopify, console), newest first, each with what happened to it: processed, duplicate, unmatched or error, and why.
Brand key, viewer role or higherMCP tool: list_eventsPaginatedlistEvents
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
Where sales reach this program (the signed event API, the Stripe and Shopify webhook URLs) and whether each Stripe or Shopify signing secret is set. Secrets are write-only: only their last 4 characters come back.
Brand key, viewer role or higherMCP tool: get_webhook_settingsgetWebhooks
Stores the signing secret (whsec_...) of the Stripe webhook endpoint you pointed at this program, so its sales are verified. Send an empty string to clear it.
Brand key, owner role or higherMCP tool: set_stripe_webhook_secretsetStripeWebhookSecret
Field
In
Type
Required
Description
programId
path
string
Yes
The program id (prg_...), from GET /programs.
secret
body
string
Yes
The Stripe webhook signing secret, whsec_..., or "" to clear it. up to 250 chars
Builds your customer link with sub IDs (sub1 to sub5, up to 80 characters each) and an optional deep link to a page on the brand's own site. Sub IDs are kept with each click and sale, and appear in your stats and postbacks. Nothing is stored: a link is your link plus these parameters, so you can also build it yourself.
Partner key, read scope or writeMCP tool: build_linkbuildMyLink
Field
In
Type
Required
Description
program
path
string
Yes
One of your programs: its id (prg_...), its slug, or your membership id (prt_...).
sub1
body
string
No
Your label sub1. up to 80 chars
sub2
body
string
No
Your label sub2. up to 80 chars
sub3
body
string
No
Your label sub3. up to 80 chars
sub4
body
string
No
Your label sub4. up to 80 chars
sub5
body
string
No
Your label sub5. up to 80 chars
to
body
string
No
A page on the brand's own site to land on. A page on any other site is ignored and the program's destination is used. up to 2000 chars
Your sales in one program and your recruits' sales (where you earn the override), newest first, with what you earned on each. On a recruit's sale you see the outcome and your earning, never the customer.
Partner key, read scope or writeMCP tool: list_my_conversionsPaginatedlistMyConversions
Field
In
Type
Required
Description
program
path
string
Yes
One of your programs: its id (prg_...), its slug, or your membership id (prt_...).
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
Your balance in every program (pending, in hold, payable, being paid, paid; cents), totals per currency, and what you earned this year across all programs.
Partner key, read scope or writeMCP tool: get_my_earningsgetMyEarnings
{
"data": {
"overrideText": "10% of the commission of partners they recruit",
"totalOverrideCents": 750,
"recruits": [
{
"id": "prt_8812aa",
"name": "Jo Park",
"status": "approved",
"active": true,
"approvedCustomers": 3,
"myOverrideCents": 750
}
]
}
}
GET/api/v1/partner/marketplace
Search programs to join
The public directory: live programs of brands ViralPayouts has activated. Matches q against the name, description and brand. Shows whether you are already in each.
Partner key, read scope or writeMCP tool: search_marketplacePaginatedsearchMarketplace
Field
In
Type
Required
Description
q
query
string
No
Words to look for. up to 100 chars
limit
query
integer
No
How many items to return, 1 to 100. Default 25. min 1, max 100
cursor
query
string
No
The next_cursor of the previous page. Leave out for the first page. up to 400 chars
{
"data": [
{
"id": "prg_9f2c1a",
"slug": "acme-pro",
"name": "Acme Pro",
"brandName": "Acme",
"commission": "25% of each sale",
"recruiterOverride": "10% of the commission of partners they recruit",
"currency": "USD",
"openToAll": false,
"holdDays": 30,
"joined": false,
"page": "https://viralpayouts.com/programs/acme-pro"
}
],
"has_more": false,
"next_cursor": null
}
POST/api/v1/partner/marketplace/{program}/join
Join a program
Applies to a program as you. An open program approves you at once (unless a risk check holds the application for review); otherwise the brand reviews it. You must accept the program terms (read them at the terms URL first).
The URL ViralPayouts calls when one of your sales is recorded, approved or reversed in this program, the macros it can carry, and the latest deliveries.
Partner key, read scope or writeMCP tool: get_postbackgetMyPostback
Field
In
Type
Required
Description
program
path
string
Yes
One of your programs: its id (prg_...), its slug, or your membership id (prt_...).
How you promote (your words, main and other methods, paid-search answer, the promise to label posts as ads) and the places you promote from, each with whether ViralPayouts verified it, how, and the follower count when one was fetched. Brands see this when you apply.
Partner key, read scope or writeMCP tool: get_my_profilegetMyProfile
{
"data": {
"bio": "I write about bookkeeping tools for UK accountants.",
"promoText": "A comparison post on my blog plus two newsletter mentions a month to 3,000 accountants.",
"primaryMethod": "content_review",
"methods": [
"content_review",
"newsletter_email"
],
"paidSearch": "none",
"disclosureAttested": true,
"properties": [
{
"id": "ppt_1a2b",
"type": "website",
"identifier": "example-books.co.uk",
"verified": true,
"method": "dns_txt",
"followers": null
}
]
}
}
PUT/api/v1/partner/profile
Update your partner profile
Saves how you promote. promoText (at least 40 characters) and primaryMethod are required; methods are keys from the list in the docs (content_review, social_organic, newsletter_email, paid_search_brand ...). Fields you leave out keep their value.
{
"data": {
"promoText": "A comparison post on my blog plus two newsletter mentions a month to 3,000 accountants.",
"primaryMethod": "content_review",
"methods": [
"content_review"
],
"properties": []
}
}
GET/api/v1/partner/properties
The places you promote from
Your websites, newsletters and social accounts, with verification status, method, last check and follower counts as fetched (null when not fetched). To verify one, use the partner portal.
Partner key, read scope or writeMCP tool: list_my_propertieslistMyProperties