Skip to content

Developer Integration API Reference

Connect a custom storefront to Refermate: the capture script, the server postback API for orders, refunds, and subscriptions, response codes, and how to verify tracking.

Base URL https://partners.refermate.com · Markdown version · Create a merchant account

(01)

How it works

  1. A creator shares a Refermate link. Refermate records the click and sends the shopper to your site with an rm_click query parameter.
  2. The capture script stores that value in a first-party cookie on your site.
  3. At checkout you save the click ID with the order.
  4. When the order is paid, your server posts it to Refermate. Money moves only on these server postbacks, never on browser events.
  5. You approve conversions in Partners. Refermate bills your saved payment method after the refund hold and pays the creator.

(02)

Capture script

Add this to the <head> of every page a creator link can land on.

<script src="https://partners.refermate.com/api/pn/sdk/v1.js" data-rm-consent-mode="explicit" data-rm-max-age-days="30" defer></script>
  • Without a consent attribute, the script assumes your consent manager loaded it after consent. With data-rm-consent-mode="explicit", it stores and reads nothing until you call window.RefermateCapture.grantConsent(), and that holds on every page: call it on each page load once the shopper has accepted, including checkout, or getClick() returns null. The click is captured only on the landing page, so it is lost if consent arrives after the shopper leaves it.
  • A consent manager can decide before the deferred script loads. Keep the decision and call grantConsent() once window.RefermateCapture exists, for example from the script tag's load event.
  • window.RefermateCapture.getClick() returns the stored click ID for your checkout.
  • The cookie is _refermate_click, host-only and SameSite=Lax. data-rm-max-age-days asks for 1 to 365 days (default 30), but browsers can expire it sooner: Safari keeps cookies set by scripts for at most 7 days. The last click wins.
  • If your router rewrites the URL before deferred scripts run, drop defer.

(03)

Authentication

Send your secret postback key as Authorization: Bearer <key> (or X-Refermate-Postback-Key). Bodies are JSON, up to 16 KiB. Call these endpoints only from your server; the key must never reach a browser.

(04)

Endpoints

POST /api/partner-network/postbacks/<public-tracking-key>/conversions

Report a paid one-time order that carries a Refermate click. Post only orders with a click; an order without one is rejected and shows as a tracking error.

FieldDescription
order_idRequiredYour stable order ID, up to 500 characters. It is the idempotency key: resending the same order is safe.
click_idRequiredThe rm_click value the capture script stored for this shopper. An order without one is rejected with 422 missing_referral_click.
currencyRequiredThree-letter currency code. Only USD is accepted.
order_subtotal_centsRequiredOrder subtotal in cents, a whole number of 0 or more.
occurred_atRequiredWhen it happened, in ISO 8601 with an explicit offset and 0 to 3 fractional digits, for example 2026-09-28T17:05:00.000Z. JavaScript's toISOString() qualifies; truncate microseconds from other languages.
eligible_amount_centsOptionalThe commissionable part of the subtotal. Defaults to the subtotal and cannot exceed it.
line_itemsOptional[{ product_id, amount_minor_units, quantity }], summing to the eligible amount. Required when the program pays per product.
order_nameOptionalA customer-facing order number.
customer_idOptionalYour customer ID, for your own reporting.
discount_codeOptionalA discount code used on the order.
metadataOptionalAn object of your own data, up to 4 KiB.
testOptionaltrue only for the verification order from your setup page.
{
  "click_id": "a1B2c3D4e5F6g7H8",
  "currency": "USD",
  "eligible_amount_cents": 10000,
  "occurred_at": "2026-09-28T17:05:00.000Z",
  "order_id": "ORDER-1001",
  "order_name": "#1001",
  "order_subtotal_cents": 10000
}

POST /api/partner-network/postbacks/<public-tracking-key>/reversals

Report a full refund or cancellation of a one-time order. Partial refunds are not accepted yet. A refund that arrives after Refermate has billed you for the commission returns 422 paid_conversion_not_auto_reversed and reverses nothing; contact support to settle it.

FieldDescription
order_idRequiredThe same order ID you sent to conversions.
occurred_atOptionalWhen it happened, in ISO 8601. Defaults to when we receive the request; send it when you replay a late event.
reasonOptionalA short reason such as refunded or cancelled.
{
  "occurred_at": "2026-10-02T09:30:00.000Z",
  "order_id": "ORDER-1001",
  "reason": "refunded"
}

POST /api/partner-network/postbacks/<public-tracking-key>/v2/recurring/relationships

Bind a new subscription to the Refermate click that started it. Send this once, when the subscription is created. Add a subscription commission rule for the product in Partners first: a bind with no matching rule returns no_matching_subscription_rule and keeps that subscription at zero commission, even after you add a rule.

FieldDescription
event_idRequiredYour unique ID for this event; resending it is safe.
relationship_idRequiredYour stable subscription ID.
click_idRequiredThe rm_click value for this shopper.
product_idRequiredThe subscribed product.
price_idOptionalThe subscribed price or plan.
currencyRequiredOnly USD is accepted.
environmentRequiredAlways live for production traffic.
occurred_atOptionalWhen it happened, in ISO 8601. Defaults to when we receive the request; send it when you replay a late event.
{
  "click_id": "a1B2c3D4e5F6g7H8",
  "currency": "USD",
  "environment": "live",
  "event_id": "evt-sub-1001-created",
  "occurred_at": "2026-09-28T17:05:00.000Z",
  "product_id": "plan-pro",
  "relationship_id": "sub-1001"
}

POST /api/partner-network/postbacks/<public-tracking-key>/v2/recurring/billing-events

Report each invoice of a bound subscription, paid or not. Never send a click here: the relationship already names it.

FieldDescription
event_idRequiredYour unique ID for this event.
relationship_idRequiredThe subscription ID you bound.
invoice_idRequiredYour invoice ID.
payment_stateRequiredpaid, failed, open, void, or uncollectible. Only paid can earn a reward.
amount_paid_minor_unitsRequiredAmount paid, in cents.
eligible_amount_minor_unitsOptionalThe commissionable part. Defaults to the amount paid and cannot exceed it.
product_idRequiredThe billed product. A product or price different from the bound one holds the subscription for review.
price_idOptionalThe billed price or plan.
currencyRequiredOnly USD is accepted.
environmentRequiredAlways live for production traffic.
occurred_atRequiredWhen it happened, in ISO 8601 with an explicit offset and 0 to 3 fractional digits, for example 2026-09-28T17:05:00.000Z. JavaScript's toISOString() qualifies; truncate microseconds from other languages.
{
  "amount_paid_minor_units": 1999,
  "currency": "USD",
  "environment": "live",
  "event_id": "evt-inv-1001-paid",
  "invoice_id": "inv-1001",
  "occurred_at": "2026-09-28T17:05:00.000Z",
  "payment_state": "paid",
  "product_id": "plan-pro",
  "relationship_id": "sub-1001"
}

POST /api/partner-network/postbacks/<public-tracking-key>/v2/recurring/reversals

Report a full refund of one subscription invoice.

FieldDescription
event_idRequiredYour unique ID for this event.
relationship_idRequiredThe subscription ID.
invoice_idRequiredThe refunded invoice.
reasonOptionalA short reason.
environmentRequiredAlways live for production traffic.
occurred_atOptionalWhen it happened, in ISO 8601. Defaults to when we receive the request; send it when you replay a late event.
{
  "environment": "live",
  "event_id": "evt-inv-1001-refunded",
  "invoice_id": "inv-1001",
  "occurred_at": "2026-10-02T09:30:00.000Z",
  "reason": "refunded",
  "relationship_id": "sub-1001"
}

POST /api/partner-network/postbacks/<public-tracking-key>/v2/recurring/relationships/end

Report that a subscription ended. Later invoices for it are rejected.

FieldDescription
event_idRequiredYour unique ID for this event.
relationship_idRequiredThe subscription ID.
reasonOptionalA short reason.
environmentRequiredAlways live for production traffic.
occurred_atOptionalWhen it happened, in ISO 8601. Defaults to when we receive the request; send it when you replay a late event.
{
  "environment": "live",
  "event_id": "evt-sub-1001-ended",
  "occurred_at": "2026-12-28T17:05:00.000Z",
  "reason": "canceled",
  "relationship_id": "sub-1001"
}

(05)

Responses

Every response is JSON with ok and a machine-readable reason, for example {"ok": true, "reason": "recorded", "transaction_id": 123}. Created records add transaction_id, conversion_id, binding_id, or event_id. Branch on the status and reason, never on wording.

StatusMeaning
200Accepted, including an exact replay of an earlier request (for example duplicate_order).
400The body is not valid JSON or is missing a required field (invalid_payload, json_required, unexpected_click_id). Fix the request; do not retry it.
401Missing or wrong postback key.
403The integration is disabled or the store is archived.
404The subscription, invoice, or click named in a recurring request does not exist.
409The same ID was sent earlier with different content (duplicate_order_conflict, duplicate_event_conflict), or the environment does not match.
410A verification test link expired.
413The body is larger than 16 KiB.
422The request is valid but cannot earn, for example missing_referral_click, referral_click_already_converted, unsupported_pricing_currency, invalid_occurred_at, or relationship_ended. Do not retry. One needs you: paid_conversion_not_auto_reversed means a refund came after the commission was billed, so contact support.
5xxUsually temporary: retry the same body with backoff. 503 means pricing history is briefly unavailable. A 500 with reason duplicate_event repeats a recurring event that was already rejected; it will never succeed, so stop retrying it. A 500 with reason active_hold means the order is under a dispute or review hold; the refund succeeds only once that resolves, so retry it daily, not with fast backoff.
  • Retry only 5xx responses and network errors, with the same body. Never retry a 500 whose reason is duplicate_event, and retry active_hold daily.
  • One click backs one one-time order. A second order on the same click returns referral_click_already_converted.
  • Only USD orders earn today.
  • occurred_at may be at most 5 minutes in the future. A paid order may be at most the program's attribution window plus 7 days old; refunds and subscription events may be up to 372 days old.

(06)

Verify your integration

In Partners, open your Developer Integration setup page and choose "Create test link". Open the link on your site, place an order, and post it with "test": true and the rmv_ click ID the script stored. A 200 test_verified response turns tracking on. Test orders never create money.