> For the complete documentation index, see [llms.txt](https://flowrouter.gitbook.io/flowrouter-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://flowrouter.gitbook.io/flowrouter-docs/build-with-flowrouter/errors.md).

# Errors and retries

Handle Swap API v1 errors, request limits, and retries.

This page covers errors of the [Swap API v1](/flowrouter-docs/build-with-flowrouter/swap-api.md). Every error from the API has an HTTP status and this body:

```json
{
  "code": "SERVICE_BUSY",
  "message": "The service is busy. Try again shortly.",
  "requestId": "6f1c2a8e-0b7d-4c43-9a51-2f0e8d4b7c19"
}
```

The `X-Request-Id` header has the same `requestId`. Include it when you report a problem. Use `code` in your logic, not `message`: the message text can change.

## Error codes

| HTTP | `code`                   | Meaning                                                                                                                                                                                    | Action                                      |
| ---- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------- |
| 400  | `INVALID_REQUEST`        | A parameter is missing, unknown, repeated, empty, or out of range. Or `recipient` differs from `taker`, or the two tokens are the same.                                                    | Correct the request.                        |
| 400  | `TOKEN_NOT_SUPPORTED`    | A token is not in the current token list.                                                                                                                                                  | Check `/tokens`.                            |
| 401  | `UNAUTHORIZED`           | An `X-API-Key` header was sent, but the key is wrong, expired, or revoked, or the request has two keys.                                                                                    | Check the header, or send no key.           |
| 403  | `FORBIDDEN`              | The request has an `Origin` header, or the key does not allow this endpoint.                                                                                                               | Call from a server.                         |
| 404  | `NOT_FOUND`              | Unknown path.                                                                                                                                                                              | Use a documented endpoint.                  |
| 405  | `METHOD_NOT_ALLOWED`     | The method is not `GET`.                                                                                                                                                                   | Use `GET`.                                  |
| 422  | `NO_ROUTE`               | No executable route now.                                                                                                                                                                   | Try again later, or try another amount.     |
| 422  | `NO_EXECUTABLE_ROUTE`    | Routes exist, but each one failed its simulation at the current block.                                                                                                                     | Try again shortly, or try another amount.   |
| 422  | `INSUFFICIENT_LIQUIDITY` | The route cannot take the full sell amount. The API never returns a partial fill.                                                                                                          | Use a smaller amount.                       |
| 422  | `SIMULATION_FAILED`      | The simulation did not succeed, or the quote became stale.                                                                                                                                 | Request a new quote.                        |
| 429  | `RATE_LIMITED`           | Your client IP address or your key reached a request limit. The response has `Retry-After` in seconds.                                                                                     | Wait for `Retry-After`.                     |
| 503  | `SERVICE_BUSY`           | The service is at its limit. A price or quote can first wait up to 3 seconds for capacity. The response has `Retry-After`.                                                                 | Wait, then try again.                       |
| 503  | `SERVICE_UNAVAILABLE`    | The service cannot quote now. For example, the chain state is stale, execution is paused, or the API could not yet confirm the referral code's settings on chain. Often has `Retry-After`. | Wait, then try again.                       |
| 500  | `INTERNAL`               | The service could not validate its own response.                                                                                                                                           | Try again one time. Report the `requestId`. |

For the request limits, see [Swap API errors and limits](/flowrouter-docs/build-with-flowrouter/swap-api-reference.md#limits).

## Retries

1. On `429 RATE_LIMITED` or `503 SERVICE_BUSY`, read the `Retry-After` header. It gives the wait in seconds. Do not send the request again before that time.
2. A price or quote can first wait up to 3 seconds for capacity. Set your client timeout to at least 20 seconds for `/quote`.
3. On `503 SERVICE_UNAVAILABLE`, wait, then try again. Use `Retry-After` when the response has it.
4. On `422 NO_ROUTE`, try again later or with another amount. On `422 NO_EXECUTABLE_ROUTE`, try again shortly or with another amount. On `422 INSUFFICIENT_LIQUIDITY`, use a smaller amount. On `422 SIMULATION_FAILED`, get a new quote.
5. On `500 INTERNAL`, try again one time. Report the `requestId` if the error repeats.
6. Do not retry `400`, `401`, `403`, `404`, or `405`. Correct the request.

## Network errors

All Swap API v1 endpoints are `GET` requests and change nothing. After a connection reset or a timeout, you can send the same request again one time, after a short pause.

A response without the JSON body above does not come from the API. Examples are an edge rate limit (`429` with an HTML body), a proxy timeout (`502`, `504`), or a CDN error page. Treat it as a temporary failure. After an edge `429`, wait, then send fewer requests.

## After you send a transaction

A quote is not a transaction. After the wallet sends the transaction, do not send another one for the same swap until you know the result of the first. Read the receipt: FlowRouter's `Swap` event shows the real output. If the transaction reverts or is not sent before `expiresAt`, get a new quote.
