Every failure of this API has one shape, and every message points to an action. What follows is the full map: HTTP, admission refusals, SDK variants and the ceilings that produce a 429.
Transport and shape errors come with an HTTP code. Transaction submission is the exception: it answers 200 and puts the verdict in the body.
# toda falha da API HTTP tem a mesma forma
{ "error": "conta inexistente" }
# a submissão é diferente: 200 com o veredito no corpo
{ "accepted": false, "id": "0x8c1f…", "reason": "transação já conhecida" }Six codes cover everything. Each has an obvious action, and none of them calls for blind retries.
| Code | Meaning | What to do |
|---|---|---|
200 | Request served. On POST /tx, look at accepted in the body. | Move on to confirmation via /tx/:id. |
400 | Malformed body, invalid signature, out-of-range nonce, or a full mempool. | Fix the cause. Resending the same body yields the same 400. |
404 | Resource does not exist: account with no history, transaction not propagated, block above the head. | For a freshly sent transaction, poll again: it may be propagation. Otherwise the resource does not exist. |
429 | Rate limit exceeded or a temporary abuse block. | Honour Retry-After and slow down. An immediate retry extends the block. |
502 | The node answered, but a service above it failed. | Retry with exponential backoff. |
503 | Node unavailable — restarting, syncing, or without peers. | Wait and try again, or point at another node. |
These messages arrive in accepted: false or inside a 400 body. None of them improves with a retry that changes nothing.
| Reason | What to do |
|---|---|
nonce already used | Re-read nextNonce from /address/:end. Two transactions on the same nonce compete and only one lives. |
nonce too far ahead | The gap exceeded MAX_FUTURE_NONCE_GAP = 64. Send the intermediate transactions first. |
transaction already known | It is already in the mempool or in a block. Not an error: stop resending and read /tx/:id. |
mempool full | The node hit MEMPOOL_MAX = 50,000. Wait a few blocks or submit to another node. |
invalid signature | One of the two signatures is missing, or the payload changed after signing. Build with the SDK. |
insufficient balance | Amount plus the authorized fee exceed the liquid balance. Locked stake is not spendable. |
Six variants, and the difference between them is the decision your code makes next.
| Variant | Meaning |
|---|---|
ErroCliente::Transporte | The request never arrived: DNS, TLS, connection refused. A retry is reasonable. |
ErroCliente::Api | The node answered with an HTTP error. Carries the code and the body. |
ErroCliente::Resposta | The answer arrived but does not have the expected shape — missing field or wrong type. |
ErroCliente::Transacao | Failure to build or sign locally. Nothing was sent. |
ErroCliente::ProvaInvalida | The Merkle proof does not close against the root. Treat the node as hostile. |
ErroCliente::TempoEsgotado | The wait deadline expired. It is not a verdict on the transaction. |
All of them come from rust/src/config.rs and apply per IP. A polite client never touches them; an aggressive one is blocked for a while.
HTTP/1.1 429 Too Many Requests
Retry-After: 10
{ "error": "limite de requisições excedido" }240Requests allowed per window, per IP.10 000Window size, in milliseconds.50Maximum calls in a JSON-RPC batch.65 536Maximum size of a transaction's data field.2 000Cap on items in a page of /chain and similar endpoints.The EAVM surface has its own table, with the standard JSON-RPC 2.0 codes.