Test mode

Build and test an integration against your own test data: rk_test_ keys, a test payout rail, a test clock and a test inbox, with live data never touched.

Embed
Preview of the card
<a href="https://referalli.com/docs/test-mode"><img src="https://referalli.com/docs/_api/public/orgs/07f432f4-34b9-46a7-aaad-c0e395d2e4f9/spaces/2bf4f614-3630-4fbf-85f9-5ecafa6b7d97/pages/fa67eb26-3840-4d5d-8ce2-bcfe44019859/social-card.svg?v=3e7ae33eec8b" alt="Test mode" width="600" height="315"></a>

Every organization has a test mode: a separate copy of the organization with its own data. Programs, partners, links, clicks, referrals, commissions, payouts and webhooks all exist in test mode and behave as they do in live mode, but nothing you do there reaches your live data, your partners' real accounts or any real payment provider.

Getting into test mode

You use

How

An API key

Create the key while in test mode. Test keys start with rk_test_ and only ever reach test data. Live keys start with rk_live_ (keys created before test mode existed start with plain rk_ and stay live).

The dashboard

Turn on Test mode in the side bar. A banner shows while it's on.

A browser session against the API

Send referally-mode: test with your x-org-id.

With an API key the key decides the mode, so you don't need the header. If you send it anyway it must match the key: referally-mode: test with a live key (or live with a test key) is refused with 400 mode_mismatch, so nothing you meant for test mode ever lands in live data.

The test organization is created the first time you use it, with the same name (plus "(test)") and plan. Your team and roles are the live organization's: team members, SSO and roles can only be changed in live mode (409 live_mode_only otherwise).

Every API response carries referally-mode: live or referally-mode: test. GET /v1/org returns livemode, and webhook payloads include "livemode": false for test events.

The test organization has its own tracking token, so put the test aff.js URL and /go links on a staging site:

curl -s $BASE/v1/org -H "Authorization: Bearer $REFERALLY_TEST_KEY"
# { "id": "org_…", "livemode": false, "liveOrgId": "org_…", "trackingToken": "tk_…", … }

What behaves differently

Area

In test mode

Billing connections

Work as in live mode. Point your billing provider's test-mode webhooks at a test connection.

Payouts

Every payout method pays through the test rail: no provider is called and no money moves. Connecting a real payout provider is refused (409 test_mode_unsupported).

Emails

Never sent. They're captured in the test inbox: GET /v1/test/emails, or Settings → Test mode tools.

1099 filing

Always uses the built-in test filing provider.

Outbound webhooks

Delivered as usual, so you can test your receiver. The payload says "livemode": false.

Partner accounts

Test partners are never linked to a real person's partner portal account, even when the email matches.

Public pages

Test programs don't appear on public program pages, the marketplace or the attribution network.

The test payout rail

Test payouts complete straight away, with a reference like test_tr_po_…. To test failure handling:

To get

Use

A declined payout

An amount ending in .13 (for example $10.13).

A rejected recipient

Payout details containing +fail, for example a PayPal email dana+fail@example.com.

A failed test payout behaves like a live one: the payout is marked failed and its commissions stay owed.

The test clock

Holds, approval, payout schedules, promotion windows and retention all run on the organization's clock. In test mode you can move that clock forward instead of waiting:

curl -X POST $BASE/v1/test_clock/advance \
  -H "Authorization: Bearer $REFERALLY_TEST_KEY" -H "content-type: application/json" \
  -d '{"seconds": 2592000}'
# { "now": "2026-11-21T12:00:00.000Z", "offsetSeconds": 2592000, "approved": 3, "payoutRuns": 1 }

After moving the clock, Referalli runs what came due in that time: held commission lines are approved, scheduled payouts run on their day, and retention purges old test data. GET /v1/test_clock returns the current test time. The clock only moves forward, by up to 5 years per call, and only in test mode (409 test_mode_only with a live key).

Everything that happens in the test organization afterwards uses the test time: a payment reported now is dated by the test clock, and its hold ends relative to it.

A full test run

  1. Create a test key and a program, a commission rule (with holdDays), a partner and a link.

  2. Click the link through the test tracking token, and call associate with the click id.

  3. Create a generic billing connection and post a signed invoice_paid.

  4. POST /v1/test_clock/advance past the hold: the line is approved.

  5. Give the partner a payout profile and a tax form, then create and execute a payout run: it completes on the test rail.

Your live data is unchanged throughout.

Updated