# Error Handling

HTTP errors use an envelope such as:

```json
{
  "error": {
    "code": "invalid_parameter",
    "message": "Invalid request parameters",
    "type": "invalid_request_error"
  }
}
```

| Status / state | Typical cause | Action |
|---|---|---|
| Missing key | `EVOLINK_API_KEY` is unset | Get a key, export it, then validate with `GET /v1/credits` |
| `400` | Invalid model, field, media count, format, or callback | Run a dry run and compare with the variant matrix |
| `401` | Missing, invalid, or expired token | [Get or replace the EvoLink API key](https://evolink.ai/dashboard/keys?utm_source=github&utm_medium=readme&utm_campaign=seedance-2-5-video-gen), then validate again |
| `402` | Insufficient quota | [Open the EvoLink API key and account page](https://evolink.ai/dashboard/keys?utm_source=github&utm_medium=readme&utm_campaign=seedance-2-5-video-gen) before retrying |
| `403` | Model route is unavailable or the token lacks access | Check the official availability pages and account access |
| `429` | Rate limit | Back off with jitter; do not create duplicate tasks |
| `5xx` | EvoLink or upstream problem | Retry only after confirming no task ID was created |
| `status=failed` | Task-level business failure | Inspect the task `error` object; do not infer success from HTTP 200 |
| Poll timeout | Client stopped waiting | Query the same task ID later; do not resubmit blindly |

The shell, JavaScript, and Python examples all check missing keys, non-2xx responses, failed task status, and timeouts
