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

# Errors

> Error format, status codes and request ids.

Errors use standard HTTP status codes and one JSON shape. Every response, successful or not, carries an `X-Request-Id` header; include it when you contact support.

```json theme={null}
{ "error": { "code": "not_found", "message": "Printer not found", "request_id": "3f2b1c9e-7a4d-4e8b-9c51-6d0a2b7e4f18" } }
```

`code` is a stable, machine readable string you can switch on. `message` is for people and can change. `request_id` matches the `X-Request-Id` header.

## Status codes

| Status | Meaning |
| - | - |
| `400` | Malformed request: bad JSON, a missing or unknown field, or a value out of range (`invalid_request`) |
| `401` | Missing or invalid key (`unauthorized`) |
| `403` | The key lacks the scope (`insufficient_scope`) or your role cannot do this (`forbidden`) |
| `404` | Not found in this organization and mode (`not_found`). A resource of another organization or mode looks the same |
| `409` | Conflict with idempotency or state: `idempotency_in_progress`, `not_cancellable` for a job that already reached the agent, or `endpoint_disabled` when you replay a delivery on a disabled webhook endpoint |
| `410` | The stored file of a job you asked to reprint is gone (`file_expired`). Files are kept for 7 days; send the document again |
| `413` | Payload too large: print content over 25 MB (`content_too_large`) |
| `422` | The request is well formed but cannot be done: `invalid_content`, `invalid_content_url`, `printer_disabled`, `mode_mismatch`, `idempotency_key_reused`, and `invalid_url` for webhook endpoints |
| `429` | Rate limited, or the test mode daily cap (`test_mode_daily_cap`). Wait for `Retry-After` |
| `5xx` | A problem on our side, such as `503 storage_unavailable`. Retry with backoff |

## Handling errors

Check the status first, then `code`. Retry `429` and `5xx` with backoff, and use an `Idempotency-Key` on `POST /v1/printjobs` so a retry cannot print twice (see [Rate limits and idempotency](/guides/rate-limits-and-idempotency)). Fix the request for any other `4xx`.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { PrintEasy, PrintEasyError } from "@printeasy/sdk";

  const pe = new PrintEasy({ apiKey: process.env.PRINTEASY_API_KEY });
  try {
    await pe.printJobs.create({ printerId, title: "Invoice", contentType: "pdf_uri", content: url });
  } catch (err) {
    if (err instanceof PrintEasyError) console.error(err.status, err.code, err.requestId);
    else throw err;
  }
  ```

  ```python Python theme={null}
  from printeasy import PrintEasy, PrintEasyError

  pe = PrintEasy()
  try:
      pe.print_jobs.create({"printerId": printer_id, "title": "Invoice", "contentType": "pdf_uri", "content": url})
  except PrintEasyError as err:
      print(err.status, err.code, err.request_id)
  ```
</CodeGroup>

A print job that was accepted can still fail later. Its `state` becomes `error` and `stateMessage` holds the reason from the operating system. Watch for `printjob.error` in [webhooks](/guides/webhooks).


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