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

# API error codes reference

> View 13 API error codes, their HTTP status, and recommended action. Errors follow the {error: {code, message}} envelope on every endpoint.

<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{
__html: JSON.stringify({
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "@id": "https://rendobar.com/docs/support/errors/#article",
  "headline": "API error codes reference",
  "description": "Every API error code, its HTTP status, and recommended action. Errors follow the {error: {code, message}} envelope on all endpoints.",
  "datePublished": "2026-03-20",
  "dateModified": "2026-05-24",
  "author": { "@type": "Organization", "@id": "https://rendobar.com/#organization" },
  "publisher": { "@type": "Organization", "@id": "https://rendobar.com/#organization" },
  "isPartOf": { "@id": "https://rendobar.com/#website" }
})
}}
/>

Every error response uses the same shape:

```json theme={null}
{ "error": { "code": "ERROR_CODE", "message": "Human-readable description" } }
```

Check the HTTP status and `error.code` before reading `data`.

## Codes

| Code                   | HTTP | What to do                                                             |
| ---------------------- | ---- | ---------------------------------------------------------------------- |
| `UNAUTHORIZED`         | 401  | Missing or invalid auth. Check the `Authorization` header              |
| `FORBIDDEN`            | 403  | Authenticated but not allowed for this resource                        |
| `VALIDATION_ERROR`     | 400  | Body failed schema validation. `details.path` points at the field      |
| `INVALID_JOB_TYPE`     | 400  | Job type not registered or not on your plan                            |
| `INSUFFICIENT_CREDITS` | 402  | Top up at [app.rendobar.com/billing](https://app.rendobar.com/billing) |
| `PLAN_LIMIT`           | 403  | Plan limit hit (concurrency, file size). See [Limits](/support/limits) |
| `RATE_LIMITED`         | 429  | Back off per `Retry-After` header                                      |
| `NOT_FOUND`            | 404  | Resource doesn't exist or isn't visible to your org                    |
| `CONFLICT`             | 409  | Request conflicts with current state (e.g. cancelling a complete job)  |
| `RUNNER_ERROR`         | 502  | Processing failed on the runner. Check `error.message` for details     |
| `RUNNER_TIMEOUT`       | 504  | The job did not finish in time. No credits charged                     |
| `ORG_SUSPENDED`        | 403  | Contact `hello@rendobar.com`                                           |
| `INTERNAL_ERROR`       | 500  | Server bug. Persist? Contact support with the request ID               |

## Handle the common ones

The three you'll hit most: `INSUFFICIENT_CREDITS`, `RATE_LIMITED`, `VALIDATION_ERROR`.

<CodeGroup>
  ```ts SDK theme={null}
  import { createClient, isApiError } from "@rendobar/sdk";

  const client = createClient({ apiKey: "rb_YOUR_KEY" });

  try {
    const job = await client.jobs.create({
      type: "ffmpeg",
      params: { command: "ffmpeg -i https://example.com/video.mp4 -vf scale=1280:720 output.mp4" },
    });
  } catch (err) {
    if (!isApiError(err)) throw err;
    switch (err.code) {
      case "INSUFFICIENT_CREDITS":
        // redirect to billing
        break;
      case "RATE_LIMITED":
        // back off for err.retryAfter seconds
        break;
      case "VALIDATION_ERROR":
        // fix the request
        break;
      default:
        console.error(`API error: ${err.code} - ${err.message}`);
    }
  }
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.rendobar.com/jobs", {
    method: "POST",
    headers: {
      "Authorization": "Bearer rb_YOUR_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      type: "ffmpeg",
      params: { command: "ffmpeg -i https://example.com/video.mp4 -vf scale=1280:720 output.mp4" },
    }),
  });

  if (!res.ok) {
    const { error } = await res.json();
    switch (error.code) {
      case "INSUFFICIENT_CREDITS":
        // redirect to billing
        break;
      case "RATE_LIMITED":
        // back off per Retry-After
        break;
      case "VALIDATION_ERROR":
        // fix the body
        break;
      default:
        console.error(`API error: ${error.code} - ${error.message}`);
    }
  }
  ```

  ```python Python theme={null}
  import requests
  res = requests.post(
      "https://api.rendobar.com/jobs",
      headers={"Authorization": "Bearer rb_YOUR_KEY"},
      json={
          "type": "ffmpeg",
          "params": {"command": "ffmpeg -i https://example.com/video.mp4 -vf scale=1280:720 output.mp4"},
      },
  )
  if not res.ok:
      error = res.json()["error"]
      print(f"API error: {error['code']} - {error['message']}")
  ```
</CodeGroup>

## See also

* [Limits](/support/limits)
* [Job lifecycle](/concepts/job)
* [Authentication](/quickstart)

## Related

* [Plan limits](/support/limits): caps behind `PLAN_LIMIT` and `RATE_LIMITED`
* [Job lifecycle](/concepts/job): where `RUNNER_ERROR` and `RUNNER_TIMEOUT` surface
* [Credits and billing](/concepts/credits): `INSUFFICIENT_CREDITS` and the prepaid model
* [FAQ](/support/faq): common questions about failed jobs and refunds
* [Pricing](https://rendobar.com/pricing/): plan that lifts your concurrency and rate caps
