Why was my API call refused?
For a developer whose call to POST /api/v1/events, POST /api/v1/referral-tokens
or the Server API came back with an error. Most refusals are the wrong kind
of key, an Authorization header Refficks cannot read, or a body that reused
an idempotency key.
Check this first
Log the whole answer, not only the status:
error.code,error.messageanderror.request_id(the same as theX-Request-Idheader). The message names the cause in a sentence.Find the status and the message in the table below.
If the message is about a key, open Settings › Developer › API keys (owners and admins; choosing the Developer group opens it) and find the key's row by its first characters. A Revoked badge, a key made for an automation platform ("Made for Zapier, so it can do less than a key made here."), or a Type of Publishable key is the answer.

Likely causes
| What you see | Likely cause | Fix |
|---|---|---|
401 "An API key is required." |
No Authorization header, or one Refficks cannot read: bearer in lower case, Token …, a key in another header, or two spaces. |
Send the header exactly |
401 "That API key is not valid." |
The key was revoked, mistyped or cut short (the shortened rk_pub_abcd… from a snippet), or belongs to another Refficks service such as a staging one. |
Use a live key |
401 "That API key has expired." |
The key was made through the API with an expiry date that has passed. | Make a new key. |
403 "That key is not permitted to perform this action." on POST /events or POST /referral-tokens |
A publishable key, or a key made for Zapier, Make, n8n or Pabbly Connect. Neither may report sales. | Use a secret key |
403 "That key is not permitted to perform this action (partners:stage: Approve or decline applicants). It was made for Zapier, and keys for automation platforms cannot do this." |
An automation-platform key on a Server API endpoint it cannot use. error.details.ability names what is missing. |
Use a secret key, or do it in the dashboard. |
403 "A key made for Zapier cannot archive a partner. That is for a person to decide, in Refficks or with a secret key." |
An automation-platform key archiving or restoring a partner, switching a link or code on or off, or claiming a Stripe promotion. | Use a secret key |
403 "This key cannot approve applicants (partners:stage), so it cannot create an approved partner. …" |
An automation-platform key sent "lifecycle_stage": "approved". |
Leave lifecycle_stage out; the partner arrives as an applicant for a person to approve. |
403 "A helpdesk key can only look people up." or "A store plugin key can only report for its store." |
A key made for a helpdesk sidebar or the WordPress plugin. | Use a secret key |
403 ACCOUNT_CLOSED "This account has been closed, so its API keys no longer work." |
The workspace was closed. | A closed account |
402 BILLING_READ_ONLY "Your free trial has ended, so this workspace is read-only and its tracking is paused. …" |
The trial or subscription ended. Server API writes are refused; reads still answer. | Subscribe under Settings › Workspace › Billing. |
402 TRACKING_PAUSED "Tracking was paused when this happened, …" |
POST /events for something that happened while the workspace was unpaid. Not recorded, even after subscribing; refunds are still recorded. |
Subscribe under Settings › Workspace › Billing; tracking starts again from then. |
402 ENTITLEMENT_EXCEEDED "Your plan allows … ." |
A plan limit, such as live API keys or partners. details gives feature, limit and usage. |
Revoke what you no longer use, or change plan. |
404 NOT_FOUND |
A wrong path, an id from another workspace, or POST /referral-tokens with the referral module off. |
Not found |
405 with SERVER_ERROR "An unexpected error occurred." |
The address exists and that method is not offered, such as a write to a commission plan. Nothing broke. | Read the endpoint's methods in The Server API. |
409 IDEMPOTENCY_CONFLICT "This idempotency key was already used with a different payload." |
An Idempotency-Key reused with a body that differs, often a retry that rebuilt the body. |
Idempotency conflicts |
409 CONFLICT |
The request clashes with what is already true. The message says what. | Conflicts |
422 "Amounts are integer minor units: 29900 for $299.00." |
A decimal amount. | Validation |
422 "Refficks writes conversion.created itself, …" |
An event type Refficks writes, not you. | Validation |
422 "An Idempotency-Key header is required so a retry cannot double-count." |
No Idempotency-Key on POST /events. |
Send one. |
422 "The organization id field is prohibited." or "The organization is determined by your credentials and cannot be set on a request." |
organization_id in the body. |
Leave it out: the key decides the workspace. |
429 RATE_LIMITED "Too many requests." |
Over 600 requests a minute on POST /events, or 300 on the Server API, from your address. |
Too many requests |
503 MAINTENANCE |
A maintenance window. POST /events stays up; the Server API does not. |
Retry after Retry-After, when given. |
Diagnose it step by step
- Is it
401? The key was not accepted at all. Go to The header, then The key is not valid. - Is it
403? The key was accepted and is the wrong kind for this request. The message says which: go to The wrong kind of key. - Is it
409or422onPOST /events? The key is fine; the body is not. Readerror.details, which names each field. - Is it
429,500,502or503? Retry with backoff; see API errors and limits.
Fixes
The header
Send exactly Authorization: Bearer <SECRET_KEY>: the word Bearer with a
capital B, one space, then the whole key. Nothing else is read: not
X-Api-Key, not a query string, not Token.
curl https://go.refficks.com/api/v1/server/me \
-H "Authorization: Bearer <SECRET_KEY>"
A 200 from /server/me names the workspace and the key, which proves the
header and the key in one call.
The key is not valid
- On Settings › Developer › API keys, find the key by its first characters under Key.
- If it reads Revoked, it cannot be brought back. Create a new one (Create and manage API keys) and deploy it.
- If it is not listed at all, the key belongs to another workspace or another Refficks service. Use one from this workspace.
- If it is listed and live, the value your code sends differs from the key: check for a cut-off value, a stray quote or newline from an environment file, or the shortened form a snippet shows. The full key is shown only once; if you no longer have it, create a new one.
The wrong kind of key
| Key | Starts with | May |
|---|---|---|
| Secret key made on Settings › Developer › API keys | rk_live_ |
Everything a key can do: POST /events, POST /referral-tokens, every Server API endpoint. |
| Key made for Zapier, Make, n8n or Pabbly Connect | rk_live_ |
Partner work on the Server API only. It may not report sales, approve applicants, change programs, choose tiers, suspend, archive or restore partners, switch links or codes on or off, or claim Stripe promotions. |
| Publishable key | rk_pub_ |
The tracking script, from a web page. Nothing on this API. |
| Helpdesk or WordPress plugin key | rk_help_, rk_store_ |
Their own connection only. |
Both secret kinds begin rk_live_, so tell them apart on Settings ›
Developer › API keys: a key made for a platform is listed with "Made for
Zapier, so it can do less than a key made here." (or the platform it was made
for).
A closed account
A closed workspace's secret and helpdesk keys are refused with
ACCOUNT_CLOSED until it is reopened. A new key will not help. Its
publishable key keeps recording, and those sales wait for the reopening.
Refficks can reopen an account up to 90 days after it closed, after which its
data is deleted; write to support@refficks.com. See
Retention, erasure and closing your workspace.
Not found
- Check the path against The Server API and
the base
https://go.refficks.com/api/v1. - An id from another workspace answers
404exactly as one that does not exist. Ids are lower case; use them as the API returned them. POST /referral-tokensanswers404when the referral module is off for your workspace.
An idempotency conflict
The Idempotency-Key is the event's identity across everything your
workspace holds, from every source. error.details.event_id is the event
already recorded under it.
- A retry must send the same body. Build the body once and keep it, or
derive every field from your own records. A retry that fills
occurred_atwith the current time, or reorders nothing but changes a value, is a different body. - Give each event its own key. Name the event, not only the order:
order-1001-paidandrefund-77, never1001for both a sale and its refund. - Do not reuse another system's ids as keys. Stripe's event ids and the tracker's ids live in the same space.
A true repeat (same key, same body) is answered 200 with
"status": "duplicate", which is success.
A conflict
409 CONFLICT means the request is well formed and clashes with what is
already true. The common ones:
| Message | Fix |
|---|---|
| "A partner with that email already exists." | GET /server/partners/lookup?email=… and use that partner. |
| "That partner is already in this program." | Nothing to do; they may have been enrolled on creation. |
| "Approve this partner before adding them to a program." | Approve the applicant first (a secret key may transition them). |
| "That code is already in use." | Choose another code. |
| "This link needs a destination. Set one on the program to have it filled in automatically." | Send destination_url, or set a default destination on the program. |
| "Another code already claims that promotion. Take that claim back first." | One Stripe promotion credits one code. |
A validation error
422 lists each field and what is wrong in error.details.
- Amounts are integers in the currency's minor unit:
29900for USD 299.00,4900for ¥4,900. See Send events from your server › Amounts. - Event types Refficks writes itself (
conversion.created, and the later stages of leads, deal registrations and opportunities) are refused with a sentence naming what to send instead. A type that does not exist answers "Unknown event type." organization_idis refused everywhere. The key decides the workspace.- Fields that are not yours to set on the Server API (a partner's
status, a membership'stier_id, a code'suses_count) are refused with where they are set, never silently dropped.
Too many requests
POST /events allows 600 requests a minute and the Server API 300. Today they
are counted per IP address the requests come from, not per key, so two keys
used from one server share one allowance. A 429 carries no Retry-After:
wait for the minute to pass, then retry, and spread a large sync over several
minutes. See API errors and limits › Rate limits.
When to contact support
Write to support@refficks.com if a refusal does not match this page, or a
500 keeps happening for the same request. Include:
- the
X-Request-Id(orerror.request_id) of a failing call; - the method and path, and the time in UTC;
- the HTTP status,
error.codeanderror.message, exactly as returned; - the first 12 characters of the key, as Settings › Developer › API keys shows them;
- the request body, with customer emails removed.
Never send a whole secret key, a webhook signing secret, or a partner's payout details. Support does not need them and will not ask for them.
Related
- API errors and limits — every code, the limits, and how to retry.
- Create and manage API keys — making, replacing and revoking keys.
- Send events from your server
— the body
POST /eventsexpects. - The Server API — every endpoint and what it accepts.