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_…(orpk_…) with the right prefix. - You’re using a test key against
api-test.theorchard.devand a live key againstapi.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.