---
title: "Errors"
description: "One error envelope, a fixed set of codes, and a request id on every response."
url: https://typeship.dev/docs/typeship-api/api/errors
markdown: https://typeship.dev/docs/typeship-api/api/errors.md
section: "Get started"
---
> ## Documentation index
> Fetch the complete documentation index at https://typeship.dev/llms.txt (every page, one line each) or the full text at https://typeship.dev/llms-full.txt.
> Append .md to any docs URL, or send Accept: text/markdown, for the markdown twin of that page.

# Errors

One error envelope, a fixed set of codes, and a request id on every response.

Every error from the typeship API uses the same envelope:

```json
{
  "errors": [
    { "code": "invalid_request", "message": "name is required." }
  ],
  "request_id": "req_k3j2h8f0a1b2c3d4"
}
```

`errors` is always an array, even for a single error. `request_id` also arrives on every response as the `x-request-id` header. Quote it when reporting a problem.

## Codes

| Code                 | Status     | Retry               | When                                                                                                                                                                                      |
| -------------------- | ---------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_request`    | 400        | No                  | Malformed JSON, a failed field validation, a bad cursor, or an operation that does not apply (regenerating a repository-sourced project on demand). The message names the field.          |
| `unauthorized`       | 401        | No                  | Missing, malformed, or revoked API key. Fix the credential first.                                                                                                                         |
| `plan_limit_reached` | 402        | No                  | The account has used its included hosted generations. The response names where to lift it.                                                                                                |
| `not_found`          | 404        | No                  | The resource does not exist or belongs to another account. The two are indistinguishable on purpose.                                                                                      |
| `payload_too_large`  | 413        | No                  | A spec over 10MB, inline or fetched.                                                                                                                                                      |
| `spec_error`         | 422        | No                  | The document cannot be used as a spec at all. The message is the generator's, quoted verbatim. Warnings never cause this. See [Errors and warnings](https://typeship.dev/docs/reference/errors-and-warnings). |
| `fetch_error`        | 400 or 502 | 502 only            | The spec URL was invalid (400) or could not be fetched (502): unreachable, timed out after 15 seconds, or answered with an error status.                                                  |
| `rate_limited`       | 429        | After `Retry-After` | Too many requests. A `Retry-After` header says how long to wait. See [Rate limits](https://typeship.dev/docs/typeship-api/api/rate-limits).                                                                   |
| `internal_error`     | 500        | Once, with backoff  | The generator hit an unexpected condition. Not a problem with your spec.                                                                                                                  |

## Agent guidance

Read `errors[0].code`, never the message, and act on the table above. Three cases deserve care:

* **`plan_limit_reached` and anonymous caps are not failures to retry.** An anonymous `POST /v1/generate` succeeds with a `limits` object (`max_operations`, `omitted_operations`, `reason`, `signup_url`, `upgrade_url`); a 402 carries the same idea for hosted generation. Tell the user what was left out and where the cap lifts; do not loop on the same call.
* **`rate_limited` says how long.** Wait the `Retry-After` seconds once. Anonymous calls also carry `X-RateLimit-Limit` and `X-RateLimit-Remaining` on every response, so pace before the wall, not after.
* **Large results are paged and indexed.** A generation over the size cap returns `files_omitted: true` with a `files_index`; fetch the files you need with `GET /v1/generations/{id}/file?path=...` instead of asking for the whole generation again. Lists return `has_more` and `next_cursor`.

The typeship CLI turns all of this into its own envelope with stable codes and `next_steps` (below); the [typeship MCP server](https://typeship.dev/docs/typeship-api/mcp) returns the same bodies as tool errors.

## In the typeship SDK

Nothing throws. Every call returns a discriminated result, and the error side is a typed union of the documented errors for that operation. The envelope is the typed `body`:

```ts
const result = await client.projects.create({ name: "" });
if (!result.ok) {
  result.error.status;          // 400
  result.error.body.errors[0];  // { code: "invalid_request", message: "name can't be empty." }
  result.response?.requestId;   // "req_..."
}
```

`PaymentRequiredError`, `NotFoundError`, `UnprocessableEntityError`, and the rest are exported by name. `unwrap(result)` throws them instead. See [Results and errors](https://typeship.dev/docs/platforms/sdk#results-and-errors) for the pattern, which is the same one every SDK typeship generates uses.

## In the typeship CLI

Errors print one JSON envelope on stderr, `{status, issues: [{code, message}], docs_url, next_steps, detail}`, and exit `1`; the API's envelope above rides along as `detail.body`, and the typeship CLI's `issues[].code` is derived from the status (`NO_AUTH`, `PLAN_LIMIT`, `RATE_LIMITED`, `SPEC_INVALID`, and so on). Usage mistakes exit `2` before any request is made. See [Output and exit codes](https://typeship.dev/docs/platforms/cli#output-and-exit-codes).

## Sitemap

[Every page of these docs](https://typeship.dev/llms.txt)
