# Errors

Every error code of the PerfectVector API, and what to do about it.

> **Coming soon:** The Developer API opens soon. You can read the docs now; API keys arrive when it opens.

Every error from the API is [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem details, with
`Content-Type: application/problem+json`:

```json
{
  "type": "https://perfectvector.com/docs/api/errors#insufficient_credits",
  "title": "Not enough API credits",
  "status": 402,
  "detail": "This request needs 1 API credit. Available: 0.",
  "code": "insufficient_credits",
  "request_id": "req_4Tq8WmX2r9LcB0vZs7KpY1",
  "credits_required": 1,
  "credits_available": 0
}
```

| Member | Meaning |
|---|---|
| `code` | A stable machine code. **Branch on `code`**, never on `title` or `detail`. |
| `status` | The HTTP status. |
| `title` | A fixed English title for the code. |
| `detail` | A human explanation of this occurrence. It may change; do not parse it. |
| `request_id` | The request's ID, also in the `X-Request-ID` header. Quote it when you contact us. |
| `type` | A link to this code's section on this page. |
| Other members | Extra facts for some codes, listed below. |

Errors are never charged. A `403` or `429` whose body is not problem details comes from our network
edge, not from the API: see [Limits](/docs/api/limits#responses-from-the-edge).

A **failed conversion is not an error**: it answers `201` or `200` with `"status": "failed"`. See
[Failed conversions](#failed-conversions) below.

## All codes

| `code` | HTTP | Title | Retry? |
|---|---|---|---|
| [`invalid_request`](#invalid_request) | 400 | Invalid request | After fixing the request |
| [`invalid_api_key`](#invalid_api_key) | 401 | Invalid API key | After fixing the key |
| [`insufficient_credits`](#insufficient_credits) | 402 | Not enough API credits | After buying credits |
| [`account_suspended`](#account_suspended) | 403 | API access suspended | No; contact us |
| [`access_not_granted`](#access_not_granted) | 403 | API access not granted | No; contact us |
| [`not_found`](#not_found) | 404 | Not found | No |
| [`method_not_allowed`](#method_not_allowed) | 405 | Method not allowed | No |
| [`idempotency_conflict`](#idempotency_conflict) | 409 | Idempotency key reused | With a new key |
| [`conversion_in_progress`](#conversion_in_progress) | 409 | Conversion still in progress | After it finishes |
| [`result_not_ready`](#result_not_ready) | 409 | Result not available | After it succeeds |
| [`result_expired`](#result_expired) | 410 | Result expired | No |
| [`file_too_large`](#file_too_large) | 413 | File too large | With a smaller file |
| [`unsupported_media_type`](#unsupported_media_type) | 415 | Unsupported media type | With PNG, JPEG or WebP |
| [`invalid_image`](#invalid_image) | 422 | Invalid image | With another image |
| [`rate_limited`](#rate_limited) | 429 | Too many requests | After `Retry-After` |
| [`too_many_in_flight`](#too_many_in_flight) | 429 | Too many conversions in progress | When the running one finishes |
| [`internal_error`](#internal_error) | 500 | Internal error | Yes, with the same `Idempotency-Key` |
| [`service_busy`](#service_busy) | 503 | Service busy | After `Retry-After` |
| [`api_paused`](#api_paused) | 503 | API paused | After `Retry-After` |

## Codes

### `invalid_request`

**400.** The request has a missing, unknown or invalid part: a form field other than `image` and
`options`, no image or more than one, `options` that is not valid JSON or asks for something v1 does
not offer, a malformed `Idempotency-Key`, or a body that cannot be parsed. `errors` lists each
problem as `{"location", "message"}`, for example `{"location": "header.Idempotency-Key", …}`. The
API never echoes back what you sent.

### `invalid_api_key`

**401.** The key is missing, malformed, unknown or revoked, or its account was deleted. A key sent
anywhere but the `Authorization` header is ignored. The answer carries
`WWW-Authenticate: Bearer realm="PerfectVector API"`. See [Authentication](/docs/api/authentication).

### `insufficient_credits`

**402.** Your available API credits are lower than the request's price. Nothing started.
`credits_required` and `credits_available` give the numbers, and `X-Credits-Remaining` the balance.
Buy credits ([Credits](/docs/api/credits)), then retry with the same `Idempotency-Key`.

### `account_suspended`

**403.** We suspended the account's API access, for example for abuse or a payment problem. A new key
does not help. Contact contact@perfectvector.com. A suspension, and the lifting of one, takes effect on
the API within 30 seconds, so a request made right after we lift it can still get this error: wait 30
seconds and send it again.

### `access_not_granted`

**403.** The key is valid, but the API is not open to this account yet. Do not rotate the key.
Contact contact@perfectvector.com.

### `not_found`

**404.** No such path, or no conversion with this ID for this key's account and mode (a malformed ID
answers the same way), or no result with this index. A test key cannot see live conversions, and a
live key cannot see test ones.

### `method_not_allowed`

**405.** The path exists, but not with this HTTP method.

### `idempotency_conflict`

**409.** This `Idempotency-Key` was used in the last 24 hours for a different request (another image
or other `options`). Nothing was created or charged. Send a new key. See
[Idempotency](/docs/api/idempotency).

### `conversion_in_progress`

**409.** `DELETE` was called while the conversion is still running. `conversion_status` says
`queued` or `processing`. Delete it after it has finished.

### `result_not_ready`

**409.** The result cannot be downloaded: `result_status` says whether it is `queued`, `processing`
or `failed`. Poll `GET /v1/vectorizations/{id}` until it has succeeded.

### `result_expired`

**410.** The result was available for 24 hours after the conversion completed, and that time has
passed, or the conversion was deleted. The SVG cannot be recovered; convert the image again if you
need it. See [Results](/docs/api/results).

### `file_too_large`

**413.** The image is larger than 5 MiB, or the whole request is larger than 5 MiB plus 16 KiB.
`max_bytes` is `5242880`. A declared request size over the limit is refused before the key is
checked.

### `unsupported_media_type`

**415.** The image is not PNG, JPEG or WebP (checked from its content), or the request is not
`multipart/form-data`. `supported` lists `image/png`, `image/jpeg` and `image/webp`.

### `invalid_image`

**422.** The image cannot be read: it is empty, damaged, cut off or animated, or a side is smaller
than 100 or larger than 4096 pixels. `min_dimension` and `max_dimension` give the limits.

### `rate_limited`

**429.** You reached a per-minute limit (creates, `POST` attempts or other requests), or sent too
many invalid keys from one IP address. Wait the `Retry-After` seconds (also in `retry_after`). See
[Limits](/docs/api/limits).

### `too_many_in_flight`

**429.** Your account already has as many live conversions running as its limit allows (1 by
default). `in_flight` and `max_in_flight` give the numbers; `Retry-After` is `5`. Send the next image
when the running one has finished. (When your available credits cover only the running conversion,
you get `402 insufficient_credits` instead.)

### `internal_error`

**500.** Something went wrong on our side. Retry with the same `Idempotency-Key`. If it keeps
happening, contact us with the `request_id`.

### `service_busy`

**503.** The API is at capacity or a part of it is briefly unavailable. Wait the `Retry-After` seconds
(also in `retry_after`) and retry with the same `Idempotency-Key`.

### `api_paused`

**503.** We paused live conversions, for example during maintenance. `Retry-After` is `60`. Test keys
keep working.

## Failed conversions

When a conversion fails, the request still succeeds as HTTP (`201` from `POST`, `200` from `GET`).
The object has `"status": "failed"`, the result has an `error`, and `credits_charged` is `0`.

| `error.code` | Message | What to do |
|---|---|---|
| `processing_failed` | The image could not be vectorized. | Check the image; another image may work. |
| `timeout` | The conversion did not finish in time. Retry with a new Idempotency-Key. | Retry with a new `Idempotency-Key`. |
| `provider_unavailable` | The vectorization service was temporarily unavailable. Retry with a new Idempotency-Key. | Retry later with a new `Idempotency-Key`. |

Retry a failed conversion with a **new** key: the same key returns the same failed conversion.

[Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.
