More in Troubleshooting

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

  1. Log the whole answer, not only the status: error.code, error.message and error.request_id (the same as the X-Request-Id header). The message names the cause in a sentence.

  2. Find the status and the message in the table below.

  3. 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.

    The Keys list on Settings › Developer › API keys, with each key's masked first characters, its type and its Last used column, and an arrow at a Revoked badge.

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

  1. Is it 401? The key was not accepted at all. Go to The header, then The key is not valid.
  2. 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.
  3. Is it 409 or 422 on POST /events? The key is fine; the body is not. Read error.details, which names each field.
  4. Is it 429, 500, 502 or 503? 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

  1. On Settings › Developer › API keys, find the key by its first characters under Key.
  2. If it reads Revoked, it cannot be brought back. Create a new one (Create and manage API keys) and deploy it.
  3. If it is not listed at all, the key belongs to another workspace or another Refficks service. Use one from this workspace.
  4. 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 404 exactly as one that does not exist. Ids are lower case; use them as the API returned them.
  • POST /referral-tokens answers 404 when 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_at with 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-paid and refund-77, never 1001 for 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: 29900 for USD 299.00, 4900 for ¥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_id is refused everywhere. The key decides the workspace.
  • Fields that are not yours to set on the Server API (a partner's status, a membership's tier_id, a code's uses_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 (or error.request_id) of a failing call;
  • the method and path, and the time in UTC;
  • the HTTP status, error.code and error.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.