Status codes
Billing guarantees on errors
- Failed requests are not charged. The flat $0.01 management charge settles only after the operation succeeds. A request rejected for a bad body (400/422), missing permission (403), or a server error (5xx) costs nothing.
- An invalid key is a 401, not a 402. You will only ever see
402 Payment Requiredfor an account that actually exists and is short on credits. - Billing outages are a 503, not a 402. If Stripe or the chain RPC is unreachable, the API tells you to retry — it does not tell you to pay.
Failed actions return 500
If your Lit Action throws,/lit_action returns 500 with the action’s error
in the message, even though retrying the same request won’t fix it. A
successful response always has has_error: false, so check the status code to
detect a failed action.
When the contract refuses a management call because the key lacks permission,
every write endpoint returns 403 with the body "Permission denied". Check the
key’s scopes with GET /core/v1/list_api_keys before you retry.
Common sequences
“/lit_action returns 403.”
The message is “The provided API key is not authorized to execute the specified
action”. The key needs execute permission in a group that lists this exact
code’s CID, or a wildcard ([0]) execute grant. Check three things: that you
sent a usage key (the account key can’t run actions), that the key’s
execute_in_groups includes the group, and that the CID you registered matches
the code you sent. Changing the code by one character changes its CID. See
Run lit-action.
“/lit_action returns 400 with ‘No cached code found’.”
You sent ipfs_id without code. The server runs code by CID only if it has
already received that code and still has it cached. It does not fetch code from
IPFS. Send the code itself.
“I created an account but every call says 402.”
New accounts start with no credits.
Running Lit Actions and write/metered management calls (creating wallets,
groups, usage keys) consume credits; read-only calls (list_*, account_exists,
billing/balance) are free. Add funds to proceed.
“My key worked yesterday and now I get 401.”
The key was removed (remove_usage_api_key) or you’re sending a truncated
value. Keys are shown once at creation; verify with GET /core/v1/account_exists
and mint a new usage key from your account key if needed.
“The error body isn’t JSON.”
It is, as of API version v1.2. If you see an HTML error page you are talking
to something other than the API (a proxy, a wrong URL) — check the host and
path.