# Retries

> Attempt bounds and the operation-aware rules that decide when a request moves to the next Endpoint.

Canonical page: https://rpc.aurpay.net/docs/failsafe/retries

## Attempt bounds

A Route sets `max_attempts`, default `3`, between `1` and `10`. The effective limit is the lower of the Route value and the deployment limit, so a Route can ask for fewer attempts but not for more than the deployment allows.

Each attempt goes to a different Endpoint, and a candidate leaves the eligible set after its attempt. A Route accepts at most 100 targets; `max_attempts` defines the bounded subset used by one request.

Every attempt is bounded by an upstream timeout. That timeout applies per attempt, not to the request as a whole.

> Attempts run back to back. The Gateway does not wait between them, so client-side backoff remains your responsibility.

## Operation-aware failover

The Gateway decides whether to move to another Endpoint from two facts: how certain the failure is and whether the exact operation can be replayed safely. Route configuration supplies the candidates and attempt bound; the Gateway supplies this decision automatically.

The management API retains `retry_policy` as a deprecated compatibility field. It accepts and returns `safe_only` or `idempotent`, but neither value controls forwarding. Creation defaults to `safe_only`; updates that omit the field preserve its stored value.

Failures that clearly occur before a business result, such as connection and Endpoint configuration failures, can move any operation to the next candidate. Timeouts, interrupted responses, oversized responses, and selected upstream status responses are ambiguous because the upstream may have accepted the request before the response failed.

For an ambiguous failure, the Gateway distinguishes these operation types:

| Operation type | Ambiguous failure behavior |
|---|---|
| Stateless query or simulation | Moves to the next Endpoint within the attempt bound |
| Fixed, client-signed transaction broadcast | Replays the same request on the next Endpoint within the attempt bound |
| Endpoint-local filter, cursor, or session operation | Stops because another Endpoint does not share the same local state |
| Node signing, wallet, account, administration, mining, or other side-effecting operation | Stops after the ambiguous failure |
| Unrecognized or custom operation | Stops conservatively after the ambiguous failure |

Method matching is exact and protocol-specific. The Gateway does not infer replay behavior from a method prefix, a `read` label, or the HTTP verb alone. This matters for Endpoint-local Ethereum filter methods and for TRON, where many queries use `POST`.

A valid upstream JSON-RPC success or application error is final and does not trigger failover. Structural response failures can move to another Endpoint only when the operation classification permits replay. JSON-RPC notifications are the exception: because they do not expect a response, an ambiguous access failure or non-2xx notification attempt is not replayed on another Endpoint. The TRON HTTP API also classifies upstream HTTP status codes; see [TRON native HTTP API](https://rpc.aurpay.net/docs/chains/tron.md#native-http-api).

## Signed broadcasts

Signed broadcasts replay the exact payload supplied by the client. This includes EVM and TRON `eth_sendRawTransaction`, Solana `sendTransaction`, Bitcoin and Litecoin `sendrawtransaction`, and confirmed TRON native broadcast operations.

A later Endpoint can return a different response after the first Endpoint accepted the transaction. The Gateway preserves that response and does not rewrite `already known`, duplicate, or nonce-related application errors as success. Use the transaction hash, signature, or txID and chain-specific confirmation APIs to determine the final state.

- Bitcoin transaction rebroadcast can reveal additional network relationships, so applications with stricter privacy requirements can keep `max_attempts` low and use their own broadcast coordination.
- Solana transactions remain subject to recent-blockhash expiration; rebuild and sign a fresh transaction after expiration.
- TRON deduplicates an identical unexpired transaction by txID; an expired transaction must be rebuilt and signed again.

See [Errors and recovery](https://rpc.aurpay.net/docs/errors.md) for the final Gateway codes and client recovery actions.
