Build

Errors and status codes.

What each refusal means, whether anything was charged, and what to do next.

On this page

A refused request has this shape, on every endpoint:

{ "error": { "message": "…", "type": "…", "code": "…" } }

type is the class of error. code names the exact reason, or is null for a plain validation error. message says what to change.

Three answers add to it or differ:

  • A 402 quote, or a refused MPP credential, adds the quote and payment fields, and the problem fields type, title, status and detail.
  • An agent's request held for approval is answered 202 with the approval hold itself. See Approvals.
  • A stream that fails after it started sends the error as a data: event before [DONE].

What to retry:

  • Do not send a 400, 402 or 403 again unchanged. It fails the same way.
  • Retry a 429 or 503 after Retry-After, in seconds.
  • A 502 or 504 was not charged, or was refunded.

The statuses the gateway answers with, their error types, and whether anything was charged:

StatusTypeMeaningChargedWhat to do
202approval_requiredAn agent's request is above its approval threshold and waits for the owner. The body is the approval hold, not an error.NoWait for the decision, then send it again with x-approval-id.
400invalid_request_errorThe request is malformed or asks for something the model or endpoint does not do.NoFix the request. The message says what is wrong.
401authentication_errorNo key, a key the ledger rejects, or a missing, expired or signed-out session or read token.NoSend a valid credential.
402insufficient_quota, payment_requiredThe balance, a cap or a budget cannot cover the request (insufficient_quota), or a payment is needed or was refused (payment_required). A link above the balance has the type insufficient_balance.NoFund the balance, raise the cap, or pay the quote.
403invalid_request_error, permission_errorNot allowed: a paused key, a model or tool off the allowlist, someone else's resource, or a credential of the wrong kind.NoChange the key's settings, or use a credential that may.
404invalid_request_errorNo such model, route, receipt or resource for this credential.NoCheck the id. A routing policy no route meets is also a 404.
405invalid_request_errorThe method is not served on this path.NoUse the method the Allow header names.
408invalid_request_errorThe body arrived too slowly, or too little time was left to serve a paid call.NoSend it again.
409invalid_request_error, upstream_errorThe resource is not in a state that allows this: a taken slug, a pending deposit, a job not ready. A failed or expired batch job, and a failed video, have the type upstream_error.NoRead the message, wait or change the request, then retry.
410invalid_request_errorA batch result, a video clip or a link is no longer held or claimable.No; a result or clip was billed when it was madeResults and clips are kept for a limited time. Fetch them sooner.
413invalid_request_errorThe body is larger than the endpoint takes. The code is null, or upstream_rejected when the provider refused the size.NoSend a smaller body.
429rate_limit_errorA rate limit, an upload or job slot, or a payment already settling.NoWait for Retry-After, in seconds, then send it again.
500server_errorThe gateway itself failed.NoRetry. The receipt shows any refund.
502upstream_error, server_errorEvery eligible route failed, a payment's outcome is not known yet, or the ledger did not answer.No, or refundedRetry, or pick another model.
503service_unavailable, server_errorA model cannot serve right now, or a policy, setting or chain read did not answer.NoWait for Retry-After where given, or pick another model.
504upstream_errorNo provider answered before the deadline.NoRetry, or lower max_tokens.

The codes the gateway sends, by what you were doing. Each table is in alphabetical order. A refusal the ledger makes names its own reason as the code, and the message always says what to change.

Requests and models

Chat, text completions, the other modalities, batch jobs, tools and MCP calls.

CodeStatusWhat happenedWhat to do
audio_too_long400The file can hold more than four hours of audio.Split the file.
bad_multipart400The multipart body could not be parsed.Send a well-formed multipart body.
batch_expired409The batch job ended without a result.Nothing was charged. Submit it again.
batch_failed409The upstream failed the batch job.Nothing was charged. Submit it again.
batch_unavailable400 or 503This model, key or request cannot run as a batch job, or the gateway is not taking jobs right now (503).Use a model with batch rates, a key without no-logs, and no stream.
body_incomplete400The request body ended early.Send the whole body.
body_timeout408The request body arrived too slowly.Send it again.
context_length_exceeded400max_tokens or the prompt is larger than the model takes.Lower max_tokens or shorten the prompt.
deadline_too_close408A paid MCP call had too little time left to serve. Nothing was settled.Call again.
endpoint_not_supported400A model on attested hardware serves chat completions only.Use POST /v1/chat/completions.
gateway_restarting503The gateway is restarting and did not serve the request. Nothing was charged.Send it again.
input_too_long400The speech input is longer than the model takes.Shorten the input.
invalid_size400The image size is not WxH within the allowed range.Send a valid size.
key_privacy_unavailable503The key's privacy flags could not be read, so nothing ran.Retry after Retry-After.
max_price_unsupported400max_price was sent to an endpoint not priced per token.Drop provider.max_price there.
model_not_found404No listed model has this id.See GET /v1/models.
model_unavailable503The model is listed but cannot serve right now.Retry later, or pick another model.
model_unverified503The model has not yet returned a verified result.Pick a verified model.
no_route_for_policy404No route meets the request's provider preferences. Nothing was held.Relax the preferences.
not_multipart400The endpoint takes multipart/form-data.Send the body as multipart.
not_ready404The batch job's result is not ready yet.Poll the job until it is done.
payment_with_key400An MCP call sent both a key and a payment.Send one.
policy_unavailable503The key's or agent's policy could not be read, so nothing ran.Retry.
private_batch_unavailable400A batch job cannot run on the private tier.Send it as a normal request.
result_expired410The batch result is no longer held.Results are kept 7 days. Fetch them sooner.
settings_unavailable503The account's routing defaults could not be read, so nothing ran.Retry.
stream_cutIn a streamThe gateway restarted during the stream. Nothing was charged.Send the request again.
stream_interruptedIn a streamThe provider's stream ended before it closed the answer. What was produced is billed, and the receipt says partial.Send it again for the rest.
too_many_images400More than 16 images in one chat request.Send fewer images.
too_many_uploads429Too many uploads in progress.Retry after Retry-After.
tool_error500The tool failed. Nothing was charged.Retry.
tool_input_invalid400The input does not match the tool's input_schema.Fix the input. GET /v1/tools has the schema.
tool_input_rejected400 or the tool's 4xxThe tool's upstream refused the input, with its own status.Fix the input.
tool_not_found404No tool has this id.See GET /v1/tools.
tool_timeout504The tool's upstream did not answer in time. Nothing was charged.Retry.
tool_unavailable409The tool is disabled. Nothing was held.Use an enabled tool.
tool_upstream_error502The tool's upstream failed. Nothing was charged.Retry.
unsupported_audio400The audio container cannot be bounded before the request runs.Convert to WAV, FLAC, MP3 or Ogg.
unsupported_parameter400functions or function_call was sent.Use tools and tool_choice.
upstream_rate_limited429The tool's upstream is rate limiting.Retry after Retry-After.
upstream_rejected400 or the provider's 4xxThe provider rejected the request itself. Chat and keyed modalities answer 400; video, batch jobs and modalities paid per request pass the provider's own 4xx through, 413 for example. Nothing is charged on a key; paid per request, $0.01 is kept.Fix the request.
upstream_timeout504No provider answered before the deadline. Nothing was charged.Retry.
upstream_unavailable502Every eligible route failed. Nothing was charged.Retry, or pick another model.
wrong_endpoint400The model does not serve this endpoint.Use one of the endpoints the message names.

Video

Video jobs, polling and the clip.

CodeStatusWhat happenedWhat to do
aspect_ratio_unsupported400The model does not take this aspect_ratio, or takes none.Use one the message names, or leave it out.
gateway_restart503The gateway restarted before the clip was made or fetched. Nothing was charged.Send the request again.
image_required400The model makes video from a first frame.Send image as a PNG or JPEG data URL.
image_too_large400The first frame is too large.Send a smaller image.
image_unsupported400The model makes video from text only.Leave image out.
invalid_image400image is not a PNG or JPEG data URL that can be read.Send a PNG or JPEG data URL.
invalid_seconds400seconds is not a whole number the model takes.Use the range the message names.
negative_prompt_too_long400negative_prompt is longer than the model takes.Shorten it.
negative_prompt_unsupported400The model takes no negative_prompt.Leave it out.
prompt_too_long400The prompt is longer than the model takes.Shorten the prompt.
read_token_required401A video job paid per request needs its read token.Send Authorization: Bearer <read_token>.
restarting503This gateway instance takes no new video jobs while it restarts.Retry shortly.
size_unsupported400size is not taken: each model is sold at one resolution.Send aspect_ratio instead.
too_many_video_jobs429The key has two unbilled video jobs, or the gateway is at capacity.Fetch or wait for one first.
unsupported_resolution400resolution is not the model's one resolution.Send the model's resolution, or leave it out.
video_expired410The clip is no longer held.Clips are kept 30 minutes. Fetch them sooner.
video_failed409The video job failed. Nothing was charged.Start a new job.
video_not_ready409The clip is still being made.Poll the job until it is completed.

Limits, caps and balances

Rate limits, spend caps, budgets, allowlists and pauses, on keys and agents alike.

CodeStatusWhat happenedWhat to do
insufficient_balance402The balance cannot cover the request's hold, a payment or a link.Fund the balance, or lower max_tokens.
key_budget_exceeded402The payment is above what is left of the key's budget.Raise the budget, or pay less.
key_paused403The key is paused.Resume it with paused set to false.
model_not_allowed403The key's or the agent's allowlist does not include this model.Add it to the allowlist, or pick another model.
rate_limited429Over a rate limit.Retry after Retry-After.
request_cap_exceeded402The request's worst case is above the agent's per-request cap.Lower max_tokens, or raise the cap.
spend_limit_exceeded402A key's or agent's hourly, daily or monthly cap is reached.Wait for the window to move on, or raise the cap.
tool_not_allowed403The agent's tool allowlist does not include this tool.Add it, or use another tool.

Pay per request

x402 and MPP payments on the /x402 paths and keyless MCP calls.

CodeStatusWhat happenedWhat to do
agent_identity_invalid400The x-erc8004-agent value is malformed, or names another registry.Send the agent id, or the registry this gateway checks.
agent_identity_not_payer403The payer is not the named agent's owner or wallet.Pay from the identity's wallet, or drop the header.
agent_identity_unknown400The x-erc8004-agent id is not in the registry.Check the agent id.
authorization_used402This payment signature was already used.Sign a new payment.
funds_lease503Payments and gasless deposits pause briefly while gateway instances hand over. Nothing was charged.Retry after Retry-After.
insufficient_funds402The payer's wallet cannot fund the payment. For one minute after this or permit2_allowance_required, the address is refused in that asset with this code and Retry-After.Hold enough of the asset, then pay again. The other asset is not affected.
invalid_address400The wallet address is not a valid hex address.Send the wallet's full address.
mpp_invalid_challenge402The MPP challenge was not issued here, was altered, or is already paid.Use a fresh challenge from a new 402.
mpp_invalid_payload402The MPP payload does not have the shape its type needs.Check the credential's payload.
mpp_malformed_credential402The MPP credential could not be read.Send base64url JSON with challenge, payload and source.
mpp_payment_expired402The MPP challenge or signature has expired.Ask for a new challenge.
payment_already_resolved409This payment was already settled another way, for example refunded. Nothing was served.Sign a new payment.
payment_conflict400Both an x402 payment and an MPP credential were sent, or two credentials.Send one.
payment_in_flight429Another payment from this address is still settling.Retry after Retry-After.
payment_invalid402The payment does not verify.Check the typed data and the accept signed.
payments_busy429The gateway is settling at capacity.Retry after Retry-After.
permit2_allowance_required402USDF is not approved to Permit2.Approve once, then pay again after a minute. Paying in USDG is not affected.
quote_mismatch402The payment does not match the current quote.Ask for a new quote.
settlement_failed402The transfer did not settle. Nothing was served.Pay again.
settlement_unconfirmed502The transfer's outcome is not known yet. Nothing was served; if it lands, it is refunded automatically.Keep the transaction the message names. Pay again if you need the answer now.
x402402Payment required: the body carries the quote.Pay the quote and send the request again.

Sessions, keys and the account

Signing in, API keys, wallet linking, deposits, withdrawals, settings, statements, teams and referrals.

CodeStatusWhat happenedWhat to do
account_not_linked401The sign-in is not linked to an account yet.Finish signing in on the site.
address_in_use409This wallet is linked to another account or sub-key.Link a wallet of your own.
already_referred409The account already has a referrer.A referral is attached once.
attach_velocity429Too many accounts attached a referral code from this address.Retry later.
authorization_invalid400The USDG deposit authorization was refused. Nothing was taken.Sign the typed data the gateway returned.
authorization_used409This USDG deposit authorization was already used or cancelled.Ask for new typed data and sign again.
bad_signature400The wallet signature does not match.Sign the exact message returned.
below_minimum400 or 409The amount is below the minimum for a link, a USDG deposit or a withdrawal.Send at least the minimum the message names.
code_unavailable503A referral code could not be allocated.Retry shortly.
daily_cap429The account made the most gasless deposits it can in a day. Nothing was taken.Retry later, or send USDF.
deposit_in_flight429A gasless deposit for this account is still being processed.Retry once it has finished.
deposit_pending409A deposit is not yet final at the chain's safe head.Retry in a few minutes.
future_month400The statement's month has not started.Ask for a past or the current month.
gas_low503Gasless deposits pause while the gateway's gas is refilled. Nothing was taken.Retry later, or send USDF.
insufficient_usdg409The linked wallet holds less USDG than the deposit.Deposit less, or add USDG.
invalid_api_key401No key, or a key the ledger rejects.Send a valid key as a Bearer token.
invalid_authorization400The deposit authorization is malformed.Send the fields the typed data names.
invalid_nonce409The wallet link nonce expired or was already used.Ask for a new nonce.
invalid_session401The session token is not valid.Sign in again.
invalid_signature400The signature is not a hex signature of the right length.Send the wallet's signature of the typed data.
invalid_units400units is not a positive whole number of base units.Send units as a string of digits.
invalid_value400A key field is outside what the ledger takes.Read the message, and change that field.
invite_expired410The team invite has expired.Ask for a new one.
invite_limit409The team has the most open invites it can have.Withdraw some, or wait for answers.
key_limit409The team has the most live keys it can have.Revoke one first.
key_not_returned502The ledger did not return the new key.List the keys to see whether it was made.
key_refused409The ledger refused the key change: the active-key or hourly limit.Revoke a key, or wait.
key_revoked409The key is revoked; its limits no longer apply.Use a live key.
key_scope403This credential cannot read or act on that resource.Use the key that made it, or a session.
spend_read_failed502The key was changed, but its spend and limits could not be read back.Read the key again with GET /v1/keys/{id}/limits.
ledger_unavailable502 or 503The ledger could not be read or did not answer.Retry shortly.
link_failed409The wallet could not be linked.Read the message, then link again.
no_account404There is no ledger account for this session.Sign in again.
not_key_owner403A team key can be changed only by the member who created it.Ask its creator.
not_linked_wallet400 or 409The authorization is not signed by the account's linked wallet.Sign with the linked wallet.
not_opened409The gasless deposit could not be opened.Read the message, then try again.
org_owner_required403Only the team's owner may do this.Ask the owner.
org_refused400The ledger refused the team change.Read the message, and change the request.
org_role_required403This needs the team's owner or an admin.Ask an owner or admin.
owner_not_linked409The top-up permit is not signed by the linked wallet.Sign the permit with the linked wallet.
owner_role_fixed400 or 403The owner's role cannot change, and the owner cannot leave.Invite admins or members instead.
permit_invalid400The top-up permit was refused.Sign the permit the gateway returned.
pull_in_flight409A top-up pull is in progress.Retry once it has settled.
self_referral409An account cannot refer itself.Use another code.
self_referral_wallet409The code belongs to an account with the same linked wallet.Use another code.
session_ended401The session was signed out.Sign in again.
session_required403This needs a signed-in session, not a key.Use the session token.
session_retired401This kind of session is no longer accepted.Sign in again on the site.
signature_check_unavailable503A contract wallet's signature could not be checked on-chain.Retry shortly.
signin_unavailable401 or 503The sign-in check is unavailable.Retry shortly.
terms_unavailable503The referral terms could not be read.Retry shortly.
topup_in_flight409A top-up pull from the current wallet is in progress.Link the new wallet once it has settled.
unauthenticated401This needs a signed-in session, or the session expired.Sign in and send the session token.
unknown_account404 or 409There is no account for this session yet.Sign in again.
unknown_code404No account has that referral code.Check the code.
wallet_locked409The balance must be withdrawn before another wallet is linked.Withdraw first, then link the new wallet.
wallet_not_linked409This needs a linked wallet.Link a wallet first.
wallet_required409This needs a linked wallet: deposits, top-ups and earnings use it.Link a wallet first.
withdrawal_refused409The ledger refused the withdrawal: the minimum, the balance, or the open and daily limits.Read the message, then change the amount or wait.

Agents and approvals

Creating, funding and paying agents, approvals, and the agent's token.

CodeStatusWhat happenedWhat to do
agent_not_created409The ledger did not create the agent.Read the message, then try again.
already_decided409The approval was already decided.Read the queue for its status.
already_launched409The agent already has a launch.Each agent launches once.
approval_denied403The owner denied this approval.Change the request, or ask again.
approval_expired403The approval expired.Send the request again to queue a new one.
approval_mismatch403The approval was given for a different request.Send the approval with the request it covers.
approval_not_a_hold403The agent asked for this approval itself; it does not release a held request.Send the request without it, to be held.
approval_not_recorded500The approval was not recorded.Retry.
approval_over_approved403The request could cost more than the approval covers.Lower the request's worst case, or ask again.
approval_required202Held for the owner's approval. Nothing was charged.Poll the approval, then resend with x-approval-id.
approval_unavailable503The agent's approval threshold could not be read, so nothing ran.Retry after Retry-After.
approval_unknown_approval403No approval with this id for this agent.Check the approval id.
approval_used403The approval was already used.Each approval is single use. Ask again.
approvals_pending429Too many of the agent's requests wait for approval.Wait for the owner's decisions.
bad_approval_id400x-approval-id is not an approval id.Send the digits of the approval id.
buyback_enabled409The launch has buyback on; launches through the gateway have it off.Prepare the launch again and send that transaction.
directory_full409The gateway's agent directory is full.Use an existing agent, or retry later.
idempotency_key_reused409The same Idempotency-Key came with a different amount or recipient.Use a new key for a new payment.
key_not_issued409No key was issued for the agent.Read the message, then retry.
launch_not_recorded409The ledger did not record the launch.Read the message, then confirm again.
launch_reverted409The launch transaction reverted.Prepare and send a new launch.
launch_taken409This launch is already recorded for another agent.Each token's fees go to one agent.
launcher_not_allowed409The launchpad does not let this wallet launch right now.Retry later.
launches_disabled409The launchpad has launches turned off right now.Retry later.
launchpad_offline409This chain's launches are not prepared through the gateway.Use the robinhood chain.
launchpad_unverified409This chain's launch cannot be checked by the gateway.Use the robinhood chain.
no_key409The agent has no active key.Issue one with POST /v1/agents/{slug}/key.
no_launchpad409No launchpad serves the agent's chain.Create the agent on robinhood.
not_a_launch409The transaction is not exactly one launch the launchpad recorded.Send the launch transaction's hash.
not_confirmed409The launch does not have its confirmations yet.Retry shortly.
not_mined409The transaction is not mined yet.Retry shortly.
not_owner403Only the agent's owner may do this.Use the owner's session.
not_provisioned409The agent has no account of its own yet.Retry shortly.
not_this_agent403This key is not the agent's own.Use the agent's key.
pair_not_approved409The launchpad does not take USDG as a pair right now.Retry later.
recipient_not_agent403Under the owner's session, a payment must go to an agent.Withdraw to move a balance out.
same_account400A payment to the paying account itself.Pay another account.
slug_reserved400The agent slug is reserved.Choose another slug.
slug_taken409Another agent has this slug.Choose another slug.
too_many_agents409The owner has five agents already.Use an existing agent.
unknown_recipient404No agent or account with that id.Check the recipient.
wrong_chain404 or 409The launchpad is on another chain than this gateway.Use the gateway on Robinhood Chain.
wrong_config409The launch used a different launch configuration.Prepare the launch again and send that transaction.
wrong_deployer409The launch was not signed by the account's linked wallet.Send it from the linked wallet.
wrong_fee_receiver409The launch's creator fees go to another address.Prepare the launch again and send that transaction.
wrong_pair409The launch is not paired with USDG.Prepare the launch again and send that transaction.

USDF links, swap quotes and the USDF/USDG pool.

CodeStatusWhat happenedWhat to do
already_claimed409The link was already claimed.Nothing to claim or cancel.
amount_too_small400The amount swaps to less than one base unit of USDF.Swap more.
bad_amount400amount is not a positive integer in the token's base units.Send the amount in base units: wei for ETH.
bad_recipient400recipient is not the address that receives the USDF.Send a valid address.
bad_slippage400slippage_bps is outside the range the gateway takes.Use the range the message names.
bad_token400token is not an ERC-20 address or eth.Send a token address, or eth.
link_cancelled409 or 410The link was cancelled.Nothing to claim.
link_expired409 or 410The link expired, and its amount went back to the sender.Ask the sender for a new link.
link_not_found404No link has this token.Check the link.
no_route404No pool can fill the whole amount for this token.Swap less, or another token.
no_swap_needed400The token is USDG or USDF already.Wrap USDG with depositFor, or use the USDF.
own_link409This is your own link.Cancel it to get the amount back.
pool_unavailable503The pool could not be read.Retry shortly.
quote_unavailable503The chain did not answer the quote.Retry shortly.
token_required400token is missing.Send an ERC-20 address, or eth.
too_many_open_links409The account has the most unclaimed links it can have.Cancel some, or wait for claims.
x_identity_mismatch403The link is addressed to another X account.Sign in with that X account.
zap_unavailable503Swap quotes are served on Robinhood Chain mainnet only.Use the mainnet gateway.

Platforms and providers

Platform keys and sub-keys, and serving your own endpoint.

CodeStatusWhat happenedWhat to do
account_suspended403An endpoint of this account is suspended.Wait for the review.
bad_end_user_ref400end_user_ref is empty or too long.Send a shorter reference.
bad_models400models is empty or has more models than the gateway takes.Send the number the message names.
bad_wallet400wallet_address is not the end user's own wallet.Send the end user's wallet.
balance_remaining409The sub-key still holds the end user's USDF.Withdraw it to the sub-key's wallet first.
cross_chain_limit409The balance came in on another chain.Withdraw it on the chain it was deposited on.
duplicate_model400A model is listed twice.List each model once.
end_user_exists409This end_user_ref already has a live sub-key.Revoke it first, or reuse it.
host_suspended403An endpoint on this host is suspended.Wait for the review.
id_taken409That provider slug belongs to another account.Choose another slug.
invalid_base_url400base_url is not an https URL on a public host.Fix base_url.
invalid_key401The platform key is not valid.Send a live platform key.
invalid_provider400A registration field is invalid.Read the message, and fix that field.
no_wallet409The sub-key has no wallet to return the balance to.Set one first.
not_platform_key403This key is not a platform key.Create one with POST /v1/platform/create.
platform_key_exists409The account already has a live platform key.Revoke it first.
priced_above_sheet400A price is not far enough below the cheapest listed route.Lower it below the ceiling the message names.
private_address400base_url resolves to a private address.Use a public host.
proof_failed400No wallet proof was issued.Read the message, then ask again.
rate_lock_unavailable503The promised rates could not be read, so prices were not checked.Retry shortly.
rate_locked409A price would raise a rate a published sheet still promises.Keep it at or below the promised rate until the date named.
sub_key_limit429The platform has the most sub-keys it can have.Revoke unused sub-keys.
supplier_payer_refused403Only providers' own endpoints could serve this request, and they serve requests from a user account's own balance.Use an account key, or another model.
supply_full409The gateway lists the most providers' new models it can.Register catalog models, or fewer new ones.
suspended403This endpoint is suspended.Wait for the review.
too_many_open429The sub-key has the most open withdrawals it can have.Wait for one to be sent.
too_many_providers409The account has the most endpoints it can register.Remove one first.
too_many_today429The sub-key made the most withdrawals it can today.Retry tomorrow.
too_soon429The endpoint was changed moments ago.Retry shortly.
unresolved_host400base_url's host does not resolve.Fix the host name.
wallet_proof_required400The wallet proof is missing, expired, already used, or for another user or address.Ask for a new proof with POST /v1/platform/wallet-proof.

Public reads

Receipts, the usage log, the chain and other reads with no key.

CodeStatusWhat happenedWhat to do
chain_unavailable400 or 503The chain could not be read, or is not open for this action.Retry shortly.
loading503The list is still loading.Retry shortly.
log_integrity500The usage log is withheld while a fault is checked.Retry later.
method_not_allowed405The method is not served on this path.Use the method the Allow header names.
not_found404No such receipt, job or resource for this credential.Check the id and the credential.
not_yet_published404 or 503The request is not in the published log yet, or the log is loading.Retry in a few seconds.
unknown_chain400The chain is not one this gateway serves.Use a chain the message names.
unknown_cursor400before names no listed payment.Pass the last receipt_id of a page.

A refused MPP credential gets 402, fresh challenges and one of these problem types. The gateway's own error.code is kept beside it.

Problem typeMeaningerror.code beside it
malformed-credentialThe credential could not be read.mpp_malformed_credential
invalid-challengeNot issued by this gateway, altered, or already paid.mpp_invalid_challenge
payment-expiredThe challenge or the signature has expired.mpp_payment_expired
invalid-payloadThe payload does not have the shape its type needs.mpp_invalid_payload
verification-failedThe payment does not match the challenge, or the payer cannot fund it.payment_invalid, insufficient_funds, permit2_allowance_required, quote_mismatch, authorization_used and the rest

After permit2_allowance_required or insufficient_funds, that address is refused in that asset for one minute, with insufficient_funds and Retry-After. It can still pay in the other asset. Refunds after payment are in Refunds and refusals.

  • Retry-After is in seconds. Wait that long before sending the request again.
  • An agent's fund and pay take an Idempotency-Key. Repeating the call with the same key returns the first receipt and moves nothing. The same key with another amount or recipient gets 409 idempotency_key_reused.
  • An x402 payment signature and an approval id are each single use. Sign or ask again for a new request.
  • A request refused before it ran was not charged. A request that failed after its hold was taken is refunded, and its receipt says so.

Next: the rate limits