← Blog
shippedbrandspayouts

Bonuses and performance bounties: pay partners for more than a sale

Pay a partner a one-off bonus from their commission page or the API, or set a goal on a program, like 10 new sales before the end of the year, and every partner who reaches it is awarded a bonus automatically. Refunds are checked before a bounty's bonus is approved.

Until now, the only way to pay a partner on OpenPartner was a commission on a conversion they drove. That covers most of a partner program, but not all of it. You want to thank your top referrer for a big month. You want to pay for a launch-week push. You want to make the offer partners see everywhere else: hit 10 sales this quarter and earn $500.

The workaround was to fake a conversion. That works, and it quietly breaks your numbers: a $500 “sale” that never happened turns up in revenue, counts toward the partner’s performance tier, and confuses whoever reads the report next month.

Two new features do this properly:

  • Bonuses: pay a partner a reward that isn’t tied to a sale.
  • Performance bounties: set a goal on a program, and every partner who reaches it is awarded a bonus automatically.

Either way, a bonus is paid like a commission: it joins the partner’s next payout, and you send that payout the way you send the rest.

Bonuses

Open a partner in Admin → Partners, go to their Commission page, and use Pay a bonus. You set:

  • the amount and currency,
  • optionally a program, which the bonus counts toward in that program’s earnings,
  • optionally a note, which the partner sees next to the bonus (“Top referrer in October. Thank you!”).

A bonus is recorded as a commission, so it goes through the payout flow you already have: it shows in the partner’s earnings, joins a payout run, and appears in your exports. By default it’s approved straight away and goes into the next payout run. Tick Hold it for the holdback first and it waits out the holdback that applies to that partner and program, then is approved automatically. If no holdback applies, a held bonus waits for you to approve it.

A bonus never counts as a sale. It isn’t revenue, it isn’t a conversion, and it doesn’t move a partner up a performance tier.

From the API

If your own systems decide who gets a bonus, call POST /bonuses:

Terminal window
curl -X POST <base>/bonuses \
-H "Authorization: Bearer <your-key>" \
-H "Content-Type: application/json" \
-d '{
"partnerId": "01K…",
"programId": "01K…",
"amount": 250.00,
"currency": "USD",
"note": "Q4 launch push",
"externalRef": "q4-launch:01K…"
}'
  • externalRef makes retries safe. Send the same request again and you get the original bonus back with "replayed": true, not a second bonus. Reusing an externalRef with a different partner, program, amount or currency is refused with 409 external_ref_conflict.
  • hold: true holds it for the program’s holdback instead of approving it now.
  • The key needs the bonuses:write scope. An admin key has it. To mint a narrower key that has it, use POST /api-keys/scoped: it isn’t among the scopes offered under Admin → Integrations yet.
  • A revoked partner can’t be paid a bonus (409 partner_revoked). Reinstate them first.

Webhooks fire at each step: bonus.awarded, bonus.approved, bonus.paid and bonus.reversed. Partners who use postbacks can receive bonus.awarded and bonus.paid, with {bonus_id}, {bounty_id} and {bonus_amount} macros. The full request and response shapes are in the API reference.

Performance bounties

Each program now has a Bounties button in Admin → Programs. A new bounty is one sentence:

When a partner’s new conversions reach 10 between Nov 1 and Jan 1, pay 500 USD.

Dates are UTC, and the end date itself isn’t included, so this bounty counts conversions through December 31.

The parts you pick:

  • What counts. conversions (sales: events with a value, or one event type you choose), revenue (in the bounty’s currency), leads (signup and trial_started events), or commissions (what the partner earned on their conversions in the program).
  • New or all-time. New counts only activity between your two dates. All-time counts the partner’s whole history in the program, so partners already past the goal are paid on the first check.
  • Who can earn it. Every partner in the program, or only partners you choose.
  • A description for partners, in plain text: what counts and any rules.

How a bounty pays

  • Checked every hour. A partner who reaches the goal is awarded a bonus for the reward amount. Each partner can earn a bounty once.
  • Late conversions still count. A conversion that happened before the end date but reached OpenPartner up to 7 days later is included. After that the bounty ends.
  • Only real results count. Conversions are weighted by the partner’s share when several partners split one, and clicks flagged as fraud don’t count. A fully refunded conversion stops counting, and revenue counts net of partial refunds. That includes refunds that arrive straight from Stripe.
  • Refunds are checked before you pay. A bounty’s bonus waits out the holdback. When it ends, the daily approval job measures the goal again before approving the bonus. If refunds have taken the partner back under it, the bonus is reversed, and the partner’s Bounties page says why. If no holdback applies, the bonus waits in your review queue instead. Approving a bonus by hand, there or anywhere else, skips the re-check: the call is yours.
  • A bounty can’t feed itself. The commissions measure counts commissions on conversions only, never bonuses.
  • The goal locks once anyone has earned it. After the first award you can rename the bounty, edit its description, push the end date later, end it or archive it, but the goal, the reward, the start date and who can earn it are fixed. Until then you can still change the goal, so settle it before you launch.

What partners see

Partners get a Bounties page in their portal, with each bounty they can earn, the goal in words, your description and a progress bar. Partners who use the portal are emailed when a bounty starts, 7 days before it ends (for bounties that run longer than a week, if they haven’t earned it yet) and when they earn it. If your program runs inside your own app with portal access turned off, telling partners is up to your app.

The goal partners see is written from the bounty’s settings, never typed by hand, so a bounty can’t promise something the hourly check won’t pay.

What it costs

A bonus is billed like a flat bounty: 10% of the bonus on Revshare, 5% on Flex. It’s on your OpenPartner invoice and never comes out of the partner’s bonus. A reversed bonus is credited back. Plans that started before the current fee rule aren’t billed for bonuses until they move to it.

Partners pay nothing.

Limits worth knowing

  • One award per partner per bounty. Repeating bounties (“$100 for every 10 sales”) aren’t supported yet.
  • Revenue and commission goals count one currency, the bounty’s. Conversions in other currencies aren’t converted.
  • No click goals, leaderboards or partner groups yet.
  • Paid bonuses aren’t clawed back automatically. The refund check happens before approval, so a refund that lands after the bonus is paid doesn’t take it back.
  • Bounties are set up in the dashboard. They aren’t part of the published API, which pays and lists bonuses (GET /bonuses?bountyId=… lists a bounty’s awards).
  • On hosted OpenPartner, paying a bonus needs an active plan, even during a trial, because the bonus is billed through it, and a brand still waiting for review can’t pay one yet.
  • Bounties don’t show on your marketplace listing yet.

Get started

  • Pay a bonus: Admin → Partners → Commission on any partner.
  • Create a bounty: Admin → Programs → Bounties on any program.
  • Integrate: POST /bonuses and the bonus.* webhooks are in the API reference.
  • What it costs: Billing.