DevelopersTroubleshooting

Troubleshooting

Common errors and how to fix them. If something isn’t here, the API Reference has each endpoint’s exact status codes.

Authentication

401 Unauthorized on a request that needs a key

The key is missing, malformed, revoked, expired, or for the wrong mode. The reason is never disclosed (by design) — a 401 is generic. Check that:

  • You sent Authorization: Bearer sk_… (or pk_…) with the right prefix.
  • You’re using a test key against api-test.theorchard.dev and a live key against api.theorchard.dev — test and live are separate data and keys.
  • The key hasn’t been revoked or rotated.

403 Forbidden

The key is valid but lacks the scope for this call (e.g. calling POST /checkout/sessions with a key that doesn’t have checkout:write). Ask the operator to issue a key with the scope you need. See Authentication → scopes.

My x-tenant-slug header seems ignored on a Bearer call

That’s intentional. When you authenticate with an API key, the tenant is derived from the key and any x-tenant-slug header is ignored (it defeats leaked-key replay against another store). Only anonymous public reads use x-tenant-slug.

pk_ key rejected for a write

Publishable keys only carry browser-safe read scopes plus checkout:write. Use an sk_ key (server-side) for anything else.

Rate limits

429 Too Many Requests

You’ve exceeded the rate limit (per-key for Bearer requests, per-tenant+IP for anonymous). Honor the Retry-After header — wait that many seconds before retrying, and add backoff. Batch where you can (e.g. POST /inventory/status with many ids instead of one call per product).

Requests

400 with items_required / return_url_and_cancel_url_required on checkout

POST /checkout/sessions needs a non-empty items array and both return_url and cancel_url. Each item is { product_slug, quantity, variant_id? }. See checkout.

product_not_found / variant_not_found / product_not_available

The product_slug (or variant_id) doesn’t exist, isn’t published, or has no price in this tenant. Confirm the product is published and that you’re hitting the right tenant (right key).

CORS errors in the browser

Public reads with a pk_ key are browser-callable. If you’re calling a server-only endpoint (anything needing an sk_ key) from the browser, that’s the problem — move it to a server route. Never put an sk_ key in client code to “fix” CORS.

Webhooks

My endpoint never receives events

  • Confirm the endpoint is active and subscribed to the event type in Settings → Webhooks, and click Test to send a webhook.ping.
  • Lifecycle events (order.*, subscription.*) deliver within ~5 minutes (they’re queued, not inline) — don’t expect them instantly.
  • Check the delivery log in the admin for the response code and error.

Signature verification fails

  • Compute the HMAC over the raw request body bytes — not re-serialized JSON. Capture the body before any JSON middleware. See Verifying signatures.
  • Use the secret shown when you created or last regenerated the endpoint; a regenerate invalidates the old secret immediately.
  • An endpoint created before the signing fix won’t verify until its secret is regenerated once.

Duplicate webhook deliveries

Retries reuse the same X-Orchard-Delivery id. Dedupe on it — that’s expected and harmless if you store processed ids.

Still stuck?

Email amir@dallal.me with the request, the response status, and (for webhooks) the delivery id from the admin log.