Errors and retries
Errors
Errors always have the same shape: a stable code to branch on, a message for people, and often a hint that says what to do next.
{
"error": {
"code": "invalid_input",
"message": "A payment for this subscription is going through right now.",
"hint": "Try again in a minute."
}
}| Code | Status | Means |
|---|---|---|
invalid_input | 400 | The input or the request doesn't make sense now. details lists fields. |
unauthenticated | 401 | Missing, invalid or revoked key. |
forbidden | 403 | The key lacks a permission, or this kind of caller can't run this command. |
policy_denied | 403 | A store rule blocks this change. |
not_found | 404 | No such thing in this store. |
plan_stale | 409 | Something changed since the plan was made. Make a new plan. |
plan_not_pending | 409 | The plan was already applied, rejected, or is waiting for approval. |
already_undone | 409 | That change was already undone. |
plan_expired | 410 | Plans last 15 minutes (72 hours while waiting for approval). |
idempotency_key_reused | 422 | That Idempotency-Key was used for a different request. |
not_reversible | 422 | That change can't be undone. |
upstream_rejected | 422 | Shopify refused the change. The message says why. |
internal | 500 | Our fault. Send us the x-request-id. |
Every response has an x-request-id header. Include it when you contact us.
Retrying safely
Networks fail. To retry a change without risk of making it twice, send an Idempotency-Key header (any unique string up to 255 characters):
curl -X POST https://regular-subs.fly.dev/api/v1/subscriptions/sub_123/pause \
-H "Authorization: Bearer $USUAL_KEY" \
-H "Idempotency-Key: pause-sub_123-2026-11-07" \
-H "Content-Type: application/json" -d '{}'If a request with that key already succeeded, you get the original response back and nothing happens again. Reusing a key with a different request is refused, so a bug can't quietly apply the wrong change.
Many commands are also harmless to repeat: asking for a frequency a subscription already has returns "status": "noop" and changes nothing.
Pagination
Lists return a page and a nextCursor. Pass it back as cursor (or before, for activity) to get the next page. null means you've reached the end.
curl "https://regular-subs.fly.dev/api/v1/subscriptions?limit=100&cursor=eyJpZCI6..." -H "Authorization: Bearer $USUAL_KEY"