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

# Error reference

> Understand ECS API errors, response envelopes, and recovery paths

Every ECS API error uses the same response envelope:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "code": "resource_not_found",
    "message": "Flow function not found.",
    "docs_url": "https://docs.cloudservices.ecowestern.net/errors/resource_not_found"
  }
}
```

Use `error.code` for programmatic handling. The `message` field contains request-specific detail. The `docs_url` field links to the matching article in this section.

## Error code directory

<CardGroup cols={3}>
  <Card title="Authentication" icon="key-round" href="/errors/invalid_api_key">
    Invalid credentials, suspended accounts, and access scope.
  </Card>

  <Card title="Request and resource" icon="file-warning" href="/errors/validation_error">
    Invalid input and missing resources.
  </Card>

  <Card title="Operations" icon="triangle-alert" href="/errors/deploy_failed">
    Quotas, deployments, and unexpected failures.
  </Card>
</CardGroup>

| HTTP status | Code                           | Detailed article                                            |
| ----------: | ------------------------------ | ----------------------------------------------------------- |
|         401 | `invalid_api_key`              | [Invalid API key](/errors/invalid_api_key)                  |
|         403 | `account_suspended`            | [Account suspended](/errors/account_suspended)              |
|         403 | `permission_denied`            | [Permission denied](/errors/permission_denied)              |
|         404 | `resource_not_found`           | [Resource not found](/errors/resource_not_found)            |
|         422 | `validation_error`             | [Validation error](/errors/validation_error)                |
|         429 | `rate_limit_exceeded_billable` | [Rate limit exceeded](/errors/rate_limit_exceeded_billable) |
|         500 | `deploy_failed`                | [Deployment failed](/errors/deploy_failed)                  |
|         500 | `internal_error`               | [Internal error](/errors/internal_error)                    |
|         501 | `not_implemented`              | [Not implemented](/errors/not_implemented)                  |

## Retry strategy

* Do not retry `401`, `403`, `404`, or `422` unchanged.
* Back off before retrying `429` responses.
* Retry transient `500` responses carefully.
* Do not blindly repeat destructive operations.
* A create or redeploy request may return while its status is still `provisioning`. Use the service status endpoint before treating it as failed.

## Client handling example

```javascript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const response = await fetch(url, options);
const payload = await response.json();

if (!response.ok) {
  const code = payload.error?.code;

  if (code === "permission_denied") {
    throw new Error("Update the API key scope before retrying.");
  }

  throw new Error(payload.error?.message ?? "ECS request failed");
}
```

Private ClearLake buckets are not available through Waymark custom domains and return `not_implemented`. Use the standard ClearLake download URL flow instead.
