> ## Documentation Index
> Fetch the complete documentation index at: https://apidocs.finrock.io/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP Status Codes Returned by the Finrock REST API

> Reference for all HTTP status codes returned by the Finrock API, including what causes each error and how to resolve it in your integration.

Every response from the Finrock API includes a standard HTTP status code that tells you whether your request succeeded and, if not, what category of problem occurred. Mapping each status code to a clear handling strategy in your application makes your integration more resilient and easier to debug.

## Status Code Reference

| Code  | Status                | Meaning                                                                                                                                                               |
| ----- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200` | OK                    | The request succeeded. The response body contains the requested data or the result of the operation.                                                                  |
| `201` | Created               | A new resource was successfully created (e.g., a new wallet or transaction). The response body contains the created resource.                                         |
| `400` | Bad Request           | The request payload does not match the API specification. A required field may be missing, a value may be in the wrong format, or a parameter combination is invalid. |
| `401` | Unauthorized          | Authentication failed. The JWT is missing, malformed, expired, or the `x-api-key` header is absent or invalid.                                                        |
| `403` | Forbidden             | Authentication succeeded, but the authenticated identity does not have permission to access the requested resource.                                                   |
| `404` | Not Found             | The requested path or resource does not exist. This can indicate a typo in the URL or that an entity with the given ID has not been created yet.                      |
| `429` | Too Many Requests     | Your API key has exceeded the rate limit for this endpoint. Retry after the timestamp in the `x-rate-limit-reset` response header.                                    |
| `500` | Internal Server Error | An unexpected server-side error occurred. The platform could not process the request. A retry may succeed after a brief delay.                                        |

## Handling Common Errors

<Accordion title="401 Unauthorized — Debugging Authentication Failures">
  A `401` response means the server could not authenticate your request. Work through the following checklist:

  1. **JWT expiry** — JWTs issued by Finrock have a short validity window. Check the `exp` claim in your token to confirm it has not expired. Generate a fresh token if necessary.
  2. **Nonce uniqueness** — The JWT payload must include a unique `nonce` value for every request. Reusing a nonce causes the request to be rejected. Use a UUID or a monotonically incrementing counter.
  3. **x-api-key header** — Confirm the `x-api-key` header is present on the request and that its value matches the API key associated with your workspace.
  4. **Authorization header format** — The header must be in the form `Authorization: Token {JWT}`. Do not use `Bearer` as the prefix.

  ```bash theme={null}
  # Correct Authorization header format
  curl --request GET \
       --url https://api.finrock.io/dac/v1/wallets \
       --header 'Authorization: Token YOUR_SIGNED_JWT' \
       --header 'x-api-key: YOUR_API_KEY' \
       --header 'accept: application/json'
  ```

  See the [Authentication reference](/authentication) for full details on constructing a valid JWT.
</Accordion>

<Accordion title="400 Bad Request — Fixing Malformed Payloads">
  A `400` response means your request body or query parameters do not conform to the API schema. Common causes include:

  * A required field is missing (e.g., omitting `asset` on a create-wallet request).
  * A field value is in the wrong type or format (e.g., passing a string where a number is required).
  * An enum value is invalid (e.g., using an unsupported `destination_type`).
  * An asset ticker is misspelled or not supported.

  The response body will typically include a message field describing which field failed validation. Review it carefully, cross-reference the endpoint's parameter documentation, and correct the payload before retrying.
</Accordion>

<Accordion title="403 Forbidden — Checking Permissions">
  A `403` response means your credentials are valid, but the authenticated user or API key does not have the required permissions for the requested operation. This commonly occurs when:

  * An API key scoped to read-only operations attempts a write (e.g., creating a transaction).
  * A request targets a resource (such as a wallet or sub-account) that belongs to a different workspace.

  Contact your workspace administrator to adjust the permissions associated with your API key if you believe the access should be granted.
</Accordion>

<Accordion title="429 Too Many Requests — Backing Off and Retrying">
  A `429` response means your application has exceeded the per-minute rate limit for this endpoint. To handle it correctly:

  1. Read the `x-rate-limit-reset` header in the response to find the exact timestamp when the window resets.
  2. Suspend all requests to that endpoint until the reset time passes.
  3. Resume sending requests after the reset.

  If you are consistently hitting the rate limit under normal operating conditions, contact [support@finrock.io](mailto:support@finrock.io) to request a higher limit.

  <Warning>
    Do not retry a `429` response immediately. Tight-loop retries will not succeed and will delay your window reset. Always wait for the `x-rate-limit-reset` timestamp.
  </Warning>
</Accordion>

<Accordion title="500 Internal Server Error — Retry with Exponential Backoff">
  A `500` response indicates a transient server-side issue. These are uncommon but can occur during periods of high load or brief platform maintenance. Implement **exponential backoff** to retry safely:

  1. Wait 1–2 seconds after the first `500`.
  2. Double the wait time on each subsequent failure (e.g., 2 s → 4 s → 8 s → 16 s).
  3. Set a maximum retry count (e.g., 5 attempts) and a maximum wait ceiling (e.g., 60 seconds).
  4. If the error persists beyond your retry budget, alert your on-call team and contact [support@finrock.io](mailto:support@finrock.io).

  ```javascript theme={null}
  async function requestWithBackoff(requestFn, maxRetries = 5) {
    let delay = 1000; // 1 second
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await requestFn();
      if (response.status !== 500) return response;
      if (attempt < maxRetries - 1) {
        await new Promise(resolve => setTimeout(resolve, delay));
        delay = Math.min(delay * 2, 60000); // cap at 60 seconds
      }
    }
    throw new Error('Max retries exceeded after repeated 500 errors');
  }
  ```

  <Note>
    For transaction submission (`POST /dac/v1/transaction`), always use a `sequence_id` when retrying after a `500`. This ensures that even if the first request was processed server-side before the error was returned, a retry with the same `sequence_id` will return the original transaction rather than creating a duplicate. See the [Idempotency reference](/reference/idempotency) for details.
  </Note>
</Accordion>
