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

# Errors and retries

> Error envelope, rate-limit headers, endpoint-specific Earn errors and which failures are safe to retry across the Yield API.

## Error envelope

Earn, Trade and Borrow return the same JSON envelope for errors.

```json theme={null}
{
  "statusCode": 400,
  "timestamp": "2026-01-15T10:30:00.000Z",
  "path": "/v1/yields/example-yield",
  "message": "Yield \"example-yield\" is not enabled for this project"
}
```

| Field | Present | Meaning |
| - | - | - |
| `statusCode` | always | HTTP status. |
| `timestamp`, `path` | always | When and where the error was produced. |
| `message` | always | Human-readable text. 500 responses return a generic message. |
| `details` | `400` and typed errors such as `412` (every error on Trade) | Structured fields: `code`, `error`, `reason`, `arguments`, `retryAfter`. Trade and Borrow can also include `details.message`. |
| `validation.message` | 400 validation failures | `string[]` of constraint messages, in place of `details`. |

Branch on `statusCode` and, where present, `details.code`. Do not parse `message` text.

## Rate limits

Requests are limited per API key. Every response on a keyed route carries:

| Header | Meaning |
| - | - |
| `x-ratelimit-limit` | Requests allowed in the current window. |
| `x-ratelimit-remaining` | Requests left in the window. |
| `x-ratelimit-reset` | When the window resets, as a Unix timestamp in seconds. |
| `retry-after` | Seconds to wait. Sent on `429` responses. |

A `429` has `message: "Rate limit exceeded"`. Limits depend on your plan; see [Rate limits](/documentation/plans-limits/rate-limits).

## Retry guidance

| Status | Retry | Action |
| - | - | - |
| 400, 404 | No | Fix the request. |
| 401 | No | Fix the key. See [Authentication](/api-reference/authentication). |
| 403 | No | Region is blocked, or (Trade) the project is disabled for the provider or for Perps (`EXECUTE_FORBIDDEN`). |
| 412 | No | A precondition failed. Change state (complete KYC, wait for the yield to reopen) first. |
| 429 | Yes | Wait `retry-after` seconds, then retry. |
| 500, 502, 503 | Yes | Retry reads with exponential backoff and jitter. A `503` from a Trade or Borrow submit is final for that transaction: create a new action. |

<Warning>
  Never resubmit a signed transaction blindly. On Earn, call `GET /v1/transactions/{transactionId}` first; a different signed transaction or hash on a terminal transaction returns `412`. On Trade and Borrow, a transaction can be submitted once and any second submit returns `400`, so poll `GET /v1/actions/{id}` instead.
</Warning>

Reads and idempotent lookups are safe to retry. Creating actions is not idempotent: a retried `POST /v1/actions/enter` can create a second action, so list actions for the address first.

## Endpoint-specific Earn errors

| Status | When | Message or class |
| - | - | - |
| 400 | Per-yield call, balances query or action on a yield not enabled for your project | `Yield "<yieldId>" is not enabled for this project` |
| 400 | Action on a yield that is temporarily blocked | `<yieldId> is temporarily unavailable. Please contact the Yield.xyz team for more information.` |
| 403 | Caller region is geo-blocked for the project, or the yield is unavailable in that region (action routes) | `Access denied from <location>` |
| 412 | Enter or exit on a yield that is closed or temporarily disabled | `<yieldId> is currently closed for new deposits` / `... for withdrawals`, or `StakeTemporarilyDisabledError` (enter) / `UnstakeTemporarilyDisabledError` (exit) |
| 412 | RWA address is not allowlisted | `RwaKycError`; the message includes the issuer's `authorizeUrl` |
| 412 | RWA address is on the issuer's compliance blacklist (Dinari) | `RwaRestrictedAddressError` |
| 412 | Submitting a different signed transaction or hash for a transaction already at a terminal status | `Transaction <id> is at terminal status <status>` |
| 429 | Too many actions created (enter, exit, manage; simulate is not counted) | `Action creation rate limit exceeded` |

For RWA checks before you build an action, use [Get KYC status](/api-reference/KycController_getStatus). Geo-blocking is described in [Geo-blocking](/documentation/advanced-setup/geo-blocking/index).

## Trade and Borrow validation

Trade and Borrow report invalid request bodies as `400` with `validation.message` listing each failed constraint. Check the request body against the operation's schema before retrying.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.