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

# Error Codes

> Error codes returned by the Barker Yield Engine API.

All errors share the same response shape:

```json theme={null}
{
  "success": false,
  "code": "engine_not_deployed",
  "message": "Engine for slug 'acme-usdc-base' is still pending_deploy"
}
```

`code` is a stable machine-readable string — switch on it in your code. `message` is human-readable and may change wording over time, do not parse it.

## HTTP status code mapping

| HTTP | Meaning                                                                    |
| ---- | -------------------------------------------------------------------------- |
| 200  | Success — `success: true`, payload in `data`                               |
| 400  | Validation error — request shape or parameter invalid                      |
| 401  | Missing or invalid `X-Api-Key`                                             |
| 403  | Key valid but lacks permission for this resource (typically wrong partner) |
| 404  | Slug or resource not found                                                 |
| 409  | Idempotency conflict (webhooks only)                                       |
| 429  | Rate limit exceeded — see `Retry-After` header                             |
| 5xx  | Internal error — safe to retry with exponential backoff                    |

## Error codes

### Authentication & rate-limiting

| Code              | HTTP | When                                  | Remediation                                                             |
| ----------------- | ---- | ------------------------------------- | ----------------------------------------------------------------------- |
| `missing_api_key` | 401  | `X-Api-Key` header absent             | Add header                                                              |
| `invalid_api_key` | 401  | Header present but key not recognized | Check key, regenerate in [Portal](https://portal.barker.money/api-keys) |
| `revoked_api_key` | 401  | Key was revoked                       | Issue a new key                                                         |
| `rate_limited`    | 429  | Per-key request budget exceeded       | Honor `Retry-After`, then retry                                         |

### Product / slug

| Code                  | HTTP | When                                           | Remediation                                                                                              |
| --------------------- | ---- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `not_found`           | 404  | Slug does not exist                            | Check spelling against `GET /products`                                                                   |
| `not_owned`           | 403  | Slug exists but belongs to a different partner | Use a slug returned by your own `GET /products`                                                          |
| `engine_not_deployed` | 409  | Product is still in `pending_deploy` status    | Wait for status to flip to `active` (typically under 5 min); webhook `product.deployed` fires when ready |
| `product_paused`      | 503  | Product status is `paused`                     | Don't surface a deposit CTA; poll `/health` for resume                                                   |
| `product_deprecated`  | 410  | Product is `deprecated` — withdrawals only     | Hide deposit, allow redeem                                                                               |

### Position / address

| Code                  | HTTP | When                                                                           | Remediation                                  |
| --------------------- | ---- | ------------------------------------------------------------------------------ | -------------------------------------------- |
| `invalid_address`     | 400  | Address is not a 42-char `0x`-prefixed hex string                              | Validate before submitting                   |
| `chain_not_supported` | 400  | Address is checksum-mismatched or product chain doesn't support address format | Use the `chain_id` from the product response |

### Yield calc / fee stats

| Code              | HTTP | When                                        | Remediation                  |
| ----------------- | ---- | ------------------------------------------- | ---------------------------- |
| `invalid_amount`  | 400  | `amount` non-numeric, ≤ 0, or above `2^256` | Validate before sending      |
| `range_too_large` | 400  | `start_date`/`end_date` span > 365 days     | Split into multiple requests |
| `invalid_days`    | 400  | `days` not one of 7, 30, 180                | Use a supported value        |

### Webhooks (inbound — partner → Barker)

| Code                      | HTTP | When                                                   | Remediation                                                  |
| ------------------------- | ---- | ------------------------------------------------------ | ------------------------------------------------------------ |
| `signature_mismatch`      | 401  | HMAC verification failed                               | Check the inbound secret; ensure you signed the **raw** body |
| `missing_idempotency_key` | 400  | `Idempotency-Key` header absent                        | Add header                                                   |
| `unknown_event`           | 400  | `event_type` not in the allowlist                      | See [Webhooks → event types](/webhooks#inbound-events)       |
| `idempotency_replay`      | 200  | Same key seen before — returned with `duplicate: true` | No action; this is a successful no-op                        |

### Server-side

| Code                    | HTTP | When                                               | Remediation                                                                                  |
| ----------------------- | ---- | -------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `internal_error`        | 500  | Unexpected server error                            | Retry with exponential backoff (start at 1s, max 5 attempts)                                 |
| `chain_rpc_unavailable` | 503  | Upstream RPC down — affects `/position`, `/health` | Show cached value if available; surface "live data temporarily unavailable"; retry after 30s |

## Retry policy

| Status           | Should you retry?                                | Strategy                                                           |
| ---------------- | ------------------------------------------------ | ------------------------------------------------------------------ |
| 4xx (except 429) | **No** — request is invalid, retrying won't help | Surface to user / fix code                                         |
| 429              | **Yes**                                          | Honor `Retry-After`; if absent, exponential backoff starting at 2s |
| 5xx              | **Yes**                                          | Exponential backoff: 1s, 2s, 4s, 8s, 16s; cap at 5 attempts        |

Idempotency: all `GET` endpoints are idempotent and safe to retry. The inbound webhook endpoint is idempotent via the `Idempotency-Key` header.

## What's next

* [Rate limits](/rate-limits) — per-key budgets and `Retry-After` semantics
* [Webhooks](/webhooks) — inbound and outbound event handling
