Skip to article
Documentation menu

Reference

API errors

Find the response code and the safe next step.

Read the code, not just the status

Customer-access errors include error.code and error.message. Participation endpoints return error.code only. Use the code for logic; do not depend on message wording. Responses are not publicly cacheable.

401 · JSON (participation endpoint)
{
  "error": {
    "code": "invalid_api_key"
  }
}

Merchant-authenticated endpoints use Authorization: Bearer rs_…. Report/visit endpoints use their purpose-specific signed token in the JSON body, not the API key. Standard limits are 120 requests per API key and 300 per IP per minute. Public report/visit endpoints have their own IP limits. Back off on HTTP 429.

Enrolment, widget and participation changes

HTTP / codeSafe next step
400 invalid_requestSend valid JSON with customer_id (cus_…). PATCH also needs active as a boolean.
401 invalid_api_keyCheck the server secret and workspace; replace a revoked key. Do not expose it to the browser.
402 programme_pausedOwner checks billing and the connected Stripe account. A retry loop cannot restore access.
409 no_programmeSave Programme before requesting customer access.
409 customer_deactivatedOnly explicit owner/API reactivation enables new participation.
409 enrolment_ceiling_reachedCheck Billing or contact support. Do not repeatedly retry the same enrolment.
409 lifecycle_busyFinish/retry the same participation change before requesting its opposite.
422 unknown_customerConfirm the customer exists in this connected Stripe account and mode. PATCH also requires prior enrolment.
429 rate_limitedBack off and try again in a minute. Avoid parallel retry bursts.
503 lifecycle_sync_failedRetry the same change. Provider promotion-code status is not yet confirmed; do not claim it succeeded.

Moments, reports and prompt context

HTTP / codeSafe next step
400 invalid_requestUse the documented fields and values; moment/report bodies must fit 4,096 bytes.
400 invalid_event_timeCheck trusted timestamps: at most seven days old, five minutes future; account creation cannot be future.
401 invalid_api_keyUse a valid server API key on moments or referral-context.
401 invalid_tokenToken missing, expired, malformed, wrong purpose or wrong workspace. Fetch the appropriate fresh capability; never extend an old decision.
409 programme_pausedMoment connection changed or is unavailable. Check connection and programme access.
409 no_programmeSave Programme first.
409 event_key_conflictThe key already identifies another customer or moment. Fix your event identity mapping; do not randomise all retries.
409 decision_unavailableReport/observation no longer permitted or reservation expired. Hide the prompt. Never fabricate shown/copy outcomes.
409 referral_not_foundWait for the friend's referral webhook, then retry the same context attachment.
422 customer_not_enrolledEnrol this customer in the connected account/mode before sending moments.
422 unknown_momentSave the exact moment name in Programme.
422 unknown_customerStripe cannot verify that customer in the connected account.
429 rate_limitedBack off before retrying; keep the original event key.
503 moment_unavailableTemporary processing failure. Retry the identical event key, not a newly generated event.

changed: false on an observation is not automatically an HTTP error. It can mean duplicate or inapplicable context. Do not reinterpret it as attribution failure or issue a reward yourself. A skipped moment response is also successful HTTP: read its decision reason.

Keep retries safe

After a network timeout, the write may have succeeded. Reuse the event key, report token/outcome or lifecycle target. Respect created and changed; only the first accepted write counts.

Never log API keys, signed URLs, report/context tokens, customer emails or full Stripe objects. Give support the endpoint, time, HTTP code, error code, test/live mode and any non-secret decision ID.