MCP server for AI agents

Point any MCP client at https://viralpayouts.com/api/mcp with a ViralPayouts key as a bearer token, or connect Claude or ChatGPT by signing in (OAuth, no key). A brand key (vpk_) gets 43 tools to run programs, partners, sales and payouts. A partner key (vpp_) gets 21 tools for that partner's programs, links, stats and earnings.

43
tools for a brand key
21
tools for a partner key
2025-06-18
MCP protocol version (streamable HTTP)

Connect

The server speaks MCP over streamable HTTP: JSON-RPC 2.0 POSTs to one URL, answered with JSON, no session to keep. It authenticates with a key in the Authorization header, so your client must be able to send a header. Create the key first: a brand owner in the console (Integration tab, API keys), a partner in the portal (Your API keys). What each key and role can do.

Claude Code
claude mcp add --transport http viralpayouts https://viralpayouts.com/api/mcp \
  --header "Authorization: Bearer vpk_..."
Cursor: .cursor/mcp.json (or ~/.cursor/mcp.json)
{
  "mcpServers": {
    "viralpayouts": {
      "url": "https://viralpayouts.com/api/mcp",
      "headers": { "Authorization": "Bearer ${env:VIRALPAYOUTS_KEY}" }
    }
  }
}
Claude Desktop: claude_desktop_config.json, through the mcp-remote bridge
{
  "mcpServers": {
    "viralpayouts": {
      "command": "npx",
      "args": ["mcp-remote", "https://viralpayouts.com/api/mcp", "--header", "Authorization:${AUTH_HEADER}"],
      "env": { "AUTH_HEADER": "Bearer vpk_..." }
    }
  }
}

Apps that connect with a sign-in (Claude custom connectors, ChatGPT and other OAuth clients) need no key: see Connect from Claude or ChatGPT.

Agents can find the server at /.well-known/mcp.json, which also points to the OpenAPI document.

Connect from Claude or ChatGPT (sign in, no key)

Claude, ChatGPT and other MCP clients that connect with a sign-in can use this server without an API key. Give the app the server URL https://viralpayouts.com/api/mcp. The app registers itself, sends you to ViralPayouts to sign in and approve, and gets its own access, which you can disconnect at any time. Nothing has to be set up on the ViralPayouts side first.

StepIn Claude (claude.ai, Desktop, mobile)In ChatGPT
1. Add the serverCustomize, Connectors, Add custom connector. On a Team or Enterprise plan an Owner adds it under Organization settings, Connectors, Add, Custom.Open chatgpt.com/plugins, press +, then Add custom MCP server. Your workspace may need developer mode turned on by an admin.
2. Enter the URLName it ViralPayouts and enter https://viralpayouts.com/api/mcp. Leave the OAuth client ID and secret empty.Enter a name and https://viralpayouts.com/api/mcp. Choose OAuth as the authentication, accept the warning and create it.
3. Sign inPress Connect. Claude opens ViralPayouts.ChatGPT opens ViralPayouts when you connect.
4. ApproveSign in as a brand (email and password) or as a partner (a one-time link sent to your email). Choose the account and the access, then Approve. You go back to Claude.The same page: choose the account and the access, then Approve. You go back to ChatGPT.

What the consent page shows: the app's name, the website it will send you back to, and the accounts you can give it. A brand member chooses one brand and a role no higher than their own (viewer, manager or owner); a partner chooses read or write. The app then has exactly the tools an API key with that role or scope has. It can never change a payout account or tax form, and it stops working if you leave the brand's team.

Disconnect an app in the brand console (Integration tab, Connected apps) or in the partner portal (Connected apps). In Claude Code: claude mcp add --transport http viralpayouts https://viralpayouts.com/api/mcp, then run /mcp to sign in.

For client developersValue
Protected resource metadata (RFC 9728)https://viralpayouts.com/.well-known/oauth-protected-resource
Authorization server metadata (RFC 8414)https://viralpayouts.com/.well-known/oauth-authorization-server
Client registrationDynamic client registration (RFC 7591) at /oauth/register, or a Client ID Metadata Document (an https client_id). Public clients; redirect URIs must be https, or http on localhost or 127.0.0.1 (any port).
FlowAuthorization code with PKCE (S256 only) and the resource parameter (RFC 8707). Responses carry iss (RFC 9207).
Scopesread, write (offline_access accepted). The person can grant less on the consent page.
TokensAccess tokens last 1 hour and work only for the resource they were issued for (/api/mcp or /api/v1). Refresh tokens rotate on every use; reusing an old one disconnects the app. Revocation (RFC 7009) at /oauth/revoke.

How the tools behave

RuleWhat it means
Same rules as the consoleA tool acts with the key's brand and role (or the partner's account and scope) and calls the same functions as the console and portal, after the same ownership checks. An agent can do nothing a person with that role could not.
Same answers as the REST APIEvery tool beyond the original ten runs its REST endpoint through the same code, so its result is the REST answer: { data } or, for lists, { data, has_more, next_cursor }.
Errors say the next stepA failed call is a tool result with isError: true, the message, and "Next step: ...": which tool to call, which field to fix, or which key to ask for.
Money is in centsAmounts are in minor units of the program currency unless a field says otherwise (send_test_sale takes amount in major units).
Retries are saferefund_conversion needs an idempotencyKey; send_message, broadcast_message, join_program, send_my_message accept one. The same key returns the first answer instead of running twice.
Limits120 requests a minute per key; up to 20 requests in one JSON-RPC batch.
A first call, by hand
curl https://viralpayouts.com/api/mcp \
  -H "Authorization: Bearer vpk_..." -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_programs","arguments":{}}}'

Tools for a brand key (43)

The first 13 are the original agent tools. The rest each match one REST endpoint. “Needs” is the least role the key must have.

ToolWhat it doesNeedsREST endpoint
list_programsLists this brand's partner programs with their ids, status, commission and the pages partners apply on.ViewerOriginal tool
create_programCreates a partner program. Needs a name and a destinationUrl; everything else has a sensible default. Returns the program with its id, then call get_integration to connect the brand's checkout.OwnerOriginal tool
update_programChanges a program. Send programId and only the fields to change, for example {"programId": "...", "status": "live"}. On a live program with approved partners, a cut takes effect 3 business days later (see scheduledChange in the answer) and an increase applies at once; partners are emailed either way. A program with no partners changes at once.OwnerOriginal tool
get_integrationHow the brand's site or Stripe reports sales for one program: the signed event API and the Stripe webhook URL. Owner keys also get the signing secret.ViewerOriginal tool
send_test_saleRuns a test sale through the real pipeline for one partner of a program, to check tracking end to end. A test sale is marked as a test and never becomes payable.ManagerOriginal tool
get_program_statsOne program's results: clicks, sales, revenue, commission, fee, ROAS, earnings per click, tracking health and whether its balance covers the next 7 days of payouts. Money is in minor units (cents).ViewerOriginal tool
list_partnersThe partners of one program with their status, clicks, sales, revenue, commission and ROAS over a period. Money is in minor units (cents).ViewerOriginal tool
get_partner_statsOne partner's results in a program over a period, with their best sub IDs. Money is in minor units (cents).ViewerOriginal tool
decide_partnerApproves, rejects, suspends or reinstates a partner, or warns them about a minor breach of the program terms (they get 7 days to fix it) and clears the warning. A rejection, suspension or warning needs a reason, which the partner sees.ManagerOriginal tool
decide_conversionApproves or rejects a conversion (a sale credited to a partner). A rejection needs a reason, which the partner sees, and a reasonCode from the program terms. Once a commission is past its payment date it can only be rejected for fraud.ManagerOriginal tool
get_referral_linkBuilds an AI-resilient tracked referral URL, partner code, signed attribution token (vp_tok_...) and protocol objects (ACP affiliate_attribution and UCP attribution) for a partner in one of this brand's programs.ViewerOriginal tool
create_checkout_linkEmbeds a partner's referral parameters (ref, attribution/ref) and a signed attribution token (vp_tok_...) into a cart or checkout URL, and returns the ACP affiliate_attribution and UCP attribution objects.ViewerOriginal tool
log_agent_referralRecords an agent-tagged referral touch for a partner in this brand's program so an AI assistant or shopping agent can log discovery credit without overwriting an earlier unexpired human click.ViewerOriginal tool
whoamiWhich brand this key acts for, its role, and the network. A cheap first call to check a key works.ViewerGET /me
get_programOne program with its terms, its machine-readable rates (basis points and cents) and its product rates.ViewerGET /programs/{programId}
get_program_breakdownClicks, 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.ViewerGET /programs/{programId}/breakdown
get_fundingMoney paid in for this program and what is left, whether it covers the next 7 days of payouts, the next payout day, and the program's invoices.ViewerGET /programs/{programId}/funding
list_eventsThe 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.ViewerGET /programs/{programId}/events
browse_partnersThe 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.ViewerGET /programs/{programId}/partners
get_partnerOne partner: status and reason, application, terms accepted, payment schedule, any warning, payout readiness and balance (cents).ViewerGET /partners/{partnerId}
set_partner_payment_scheduleA 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.OwnerPATCH /partners/{partnerId}
get_partner_linksThe partner's customer link, recruit link, their links from before handles (which keep working) and their coupon code, if the program has coupons.ViewerGET /partners/{partnerId}/links
get_partner_sub_idsClicks, sales, sales value, commission earned and EPC grouped by one of the partner's sub IDs (sub1 to sub5).ViewerGET /partners/{partnerId}/sub-ids
get_partner_recruitsThe partners this partner recruited into the program, whether each is active, and the recruiter override this partner has earned on each (cents).ViewerGET /partners/{partnerId}/recruits
list_messagesThe latest messages between the brand and one partner, oldest first. Reading marks the partner's messages read.ViewerGET /partners/{partnerId}/messages
send_messageSends a message to one partner. They see it in their portal and are emailed.ManagerPOST /partners/{partnerId}/messages
broadcast_messageSends one message to every approved partner of a program. Up to 10 broadcasts an hour per brand.ManagerPOST /programs/{programId}/messages
get_ratesWhat 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.ViewerGET /programs/{programId}/rates
set_rate_rulesReplaces 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}.OwnerPUT /programs/{programId}/rates
list_recruiter_overridesEvery 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.ViewerGET /programs/{programId}/recruiter-overrides
list_clicksCounted 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.ViewerGET /programs/{programId}/clicks
list_conversionsSales and app events credited to partners, newest first, with the commission, override and fee on each (cents, after refunds).ViewerGET /programs/{programId}/conversions
get_conversionOne conversion with its attribution, sub IDs, coupon, product, hold date and the money on it.ViewerGET /conversions/{conversionId}
refund_conversionRecords 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.OwnerPOST /conversions/{conversionId}/refund
list_ledgerEvery 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.ViewerGET /programs/{programId}/ledger
list_balancesPer partner: pending (awaiting approval), in hold (approved, before its payment date), payable, being paid, paid, and earned this year. Cents; test sales left out.ViewerGET /programs/{programId}/balances
list_payoutsPayouts to partners, newest first: amount, method (whop or manual bank transfer), status (pending, paid, failed, held) and where a rail payout stands.ViewerGET /programs/{programId}/payouts
get_payoutOne payout.ViewerGET /payouts/{payoutId}
list_payout_batchesPayout 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.ViewerGET /programs/{programId}/payout-batches
get_payout_batchOne payout run with its summary and its payouts (up to 500).ViewerGET /payout-batches/{batchId}
get_webhook_settingsWhere 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.ViewerGET /programs/{programId}/webhooks
set_stripe_webhook_secretStores 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.OwnerPUT /programs/{programId}/webhooks/stripe
set_shopify_webhook_secretStores the Shopify webhook signing secret for this program's order webhooks. Send an empty string to clear it.OwnerPUT /programs/{programId}/webhooks/shopify

Tools for a partner key (21)

A partner key sees only these. “Needs” is the key's scope: read, or write for tools that change something.

ToolWhat it doesNeedsREST endpoint
get_my_accountYour account (the person across every program), your public page and the key making the call.ReadGET /partner/me
list_my_programsEvery program you have joined or applied to, with your membership status and the program's.ReadGET /partner/programs
get_my_programYour membership of one program: its terms, your links and coupon, your balance (cents) and why it is not paid yet if it is not.ReadGET /partner/programs/{program}
get_my_linksYour customer link, your recruit link (people who join through it are your recruits and earn you the override) and your coupon code.ReadGET /partner/programs/{program}/links
build_linkBuilds 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.ReadPOST /partner/programs/{program}/links
get_my_statsYour clicks, sales, sales value, commission earned and EPC in one program, grouped by one sub ID, with totals. Cents.ReadGET /partner/programs/{program}/stats
get_my_breakdownYour clicks, sales and commission in one program grouped by the visitor's country or device.ReadGET /partner/programs/{program}/breakdown
list_my_conversionsYour 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.ReadGET /partner/programs/{program}/conversions
list_my_payoutsPayouts to you from one program, newest first.ReadGET /partner/programs/{program}/payouts
get_my_earningsYour balance in every program (pending, in hold, payable, being paid, paid; cents), totals per currency, and what you earned this year across all programs.ReadGET /partner/earnings
list_my_recruitsThe partners you recruited into one program, whether each is active, and the override you earned on each (cents), with the total.ReadGET /partner/programs/{program}/recruits
search_marketplaceThe public directory: live programs of brands ViralPayouts has activated. Matches q against the name, description and brand. Shows whether you are already in each.ReadGET /partner/marketplace
join_programApplies 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).WritePOST /partner/marketplace/{program}/join
get_postbackThe 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.ReadGET /partner/programs/{program}/postback
set_postbackSets or clears (null) the postback URL for one program. Use macros such as {click_id}, {payout} and {status}.WritePUT /partner/programs/{program}/postback
test_postbackCalls your postback URL once with sample values and returns what happened. Up to 10 an hour per program.WritePOST /partner/programs/{program}/postback/test
list_my_messagesThe latest messages between you and the brand of one program, oldest first. Reading marks the brand's messages read.ReadGET /partner/programs/{program}/messages
send_my_messageSends a message to the brand of one of your programs. Up to 20 an hour per program.WritePOST /partner/programs/{program}/messages
get_my_profileHow 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.ReadGET /partner/profile
update_my_profileSaves 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.WritePUT /partner/profile
list_my_propertiesYour 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.ReadGET /partner/properties