Use the API
Use the API to read, create, and update program records from your server. Each key works for one program. Only the program owner can create or revoke keys.
Create a key
- Open API keys in your dashboard.
- Enter a name, such as Billing server.
- Choose Create API key.
- Choose Copy API key and save it on your server.
- Close the window. The full key cannot be shown again.
Do not put the key in browser code, a public repository, or a screenshot. You can keep up to 20 active keys. Choose Revoke key when you no longer use one. Removing the owner’s access also stops their keys.

Make a request
The base path is /api/v1 on your Referral Bear site. Send the key in the Authorization header.
curl "$REFERRAL_BEAR_URL/api/v1/partners?limit=10" \
-H "Authorization: Bearer $REFERRAL_BEAR_API_KEY"Set REFERRAL_BEAR_URL to your site’s origin and REFERRAL_BEAR_API_KEY to the saved key. A list response has success, data, has_more, and total_count.
Read records
| Path | Records | Extra filters |
|---|---|---|
/programs | The key’s program | None |
/partners | Affiliates | group_id, email, status |
/customers | Referred customers | partner_id, email, status |
/links | Referral links | partner_id, parameter, value |
/commissions | Commissions | partner_id, customer_id, approval, settlement |
/transactions | Payments | partner_id, customer_id |
/promotion-codes | Coupon codes | partner_id, group_id, code |
Add a record ID to any path except /programs to read one record. For example, use /partners/RECORD_ID. Its response has success and data.
Use GET to read these routes. Create and update actions are listed below. Deletion, refunds, expanded data and most Tolt field aliases are not available through this API yet. Use Referral Bear record IDs. Imported source IDs are not route IDs. The key’s program is used by default. If you send program_id, it must match the key.
Filter and page
List routes, except /programs, accept these fields:
| Field | Value |
|---|---|
limit | 1 to 100. Default: 10. |
order | asc or desc, sorted by creation date. Default: desc. |
created_gte | Include records created at or after this date. |
created_lte | Include records created at or before this date. |
starting_after | The last record ID from the page you just read. |
ending_before | The first record ID from the page you just read. |
Use a full date with a time zone, such as 2026-09-01T00:00:00Z. Keep the same filters and order as you move between pages. Use one cursor at a time. total_count counts every record that matches the filters. has_more tells you if more rows remain in the direction you requested.
Filters match exact values. Email filters ignore letter case. For commissions, approval and settlement are separate fields. Use the values saved on the record. Amounts use the smallest currency unit, such as cents for USD. Private system fields, connection secrets and login details are not returned.
Handle errors
The limit is 25 requests per second for each key. A 429 response includes Retry-After: 1. Wait, then retry. A 401 means the key is missing, invalid, revoked, or its owner lost access. A 403 means the request names another program. A 404 means the record or route was not found. A 400 means a query field is invalid. Unknown filters are rejected.
Error responses have success: false and an error object with message and type. Read responses are not cached.
Create records
Use POST with a JSON body. All amounts are whole numbers in the currency’s smallest unit. For USD, 2500 means $25.00.
| Path | Required fields | Other fields |
|---|---|---|
/partners | name, email | group_id, status (pending or active) |
/customers | partner_id, name, identifier | email, link_id, status, created_at, subscription_id, stripe_customer_id |
/links | partner_id, value, destination | parameter (default: ref) |
/commissions | partner_id, amount, currency | approval (default: pending), note |
/transactions | customer_id, amount, currency, occurred_at, billing_type | note, product_id, quantity, interval |
Customer status can be lead, trialing, active, canceled or suspended. The default is lead. A supplied link must belong to that affiliate. Creating a lead can run the program’s signup flows.
A payment’s billing_type is one_time or subscription. Its date needs a time zone. A quantity needs a product ID. A manual payment runs the same fraud and commission rules as one entered in the dashboard. A manually created commission is separate from a payment. It does not run payment rules or send money.
For payments and commissions, send a UUID in the Idempotency-Key header. Reuse it only when retrying the same request. The first request returns 201. A repeat returns 200 and the same record. Changing the amount or other saved input while reusing the key returns 409.
curl -X POST "$REFERRAL_BEAR_URL/api/v1/commissions" \
-H "Authorization: Bearer $REFERRAL_BEAR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: REPLACE_WITH_A_UUID" \
-d '{"partner_id":"REPLACE_WITH_CREATOR_ID","amount":2500,"currency":"USD","note":"Referral bonus"}'A successful create response has success, data and created. Affiliate email addresses, customer identifiers and referral codes must be unique in the program. Repeating one of those creates returns 409. Read the existing record before trying again. JSON bodies are limited to 32 KB. Unknown fields are rejected.
Update records
Use PUT /api/v1/partners/:id, PUT /api/v1/customers/:id, or PUT /api/v1/links/:id. Send only the fields you want to change. Other fields stay the same. A successful update returns HTTP 200 with the saved record.
| Record | Fields you can change |
|---|---|
Affiliate (partners) | name, status, group_id, country_code, company_name, website |
| Customer | name, email, status, subscription_id |
| Link | param (or parameter), value, destination, disabled |
Affiliate status can be pending, active, suspended, or rejected. Customer status can be lead, trialing, active, canceled, or suspended. Setting a customer to canceled or suspended keeps that choice when payment events arrive. Setting another status clears that override.
Use a two-letter country code, such as US. Groups must belong to the same program. You can clear a customer email or subscription ID with null.
curl -X PUT "https://referral-otter.fly.dev/api/v1/links/YOUR_LINK_ID" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"param":"via","value":"jamie"}'Old referral codes still point to the same link after an edit. Another affiliate cannot take them. A code already owned by another link returns HTTP 409. Send disabled: true to turn off a link.
Affiliate email changes, customer attribution changes, payment edits, and commission edits are not part of these update routes yet. Unknown fields return HTTP 400.
Changing subscription_id replaces that one subscription in the customer’s saved list. Other imported subscriptions stay in the list. Clearing it removes only that one entry. Stripe subscription IDs start with sub_.