# Errors

Every error Fylane can return — 36 codes across 12 HTTP statuses — with whether retrying helps.

Every error carries the same shape and answers the same four questions: what happened, whether retrying helps, what to change, and where to read more. Switch on `code`, never on `message` — messages are written for humans and are allowed to improve.

The envelope

```json
{
  "type": "https://fylane.dev/errors/unsupported-file",
  "code": "unsupported_file",
  "message": "This file format is not supported.",
  "retryable": false,
  "request_id": "req_01JBQ8Z5T7WXK9MNP2RSTVA3C4",
  "docs_url": "https://fylane.dev/docs/errors/unsupported-file"
}
```

> **A 404 never confirms that something exists**
>
> A resource belonging to another organisation returns 404, not 403. A 403 would tell an attacker the id is real, which is exactly the thing worth hiding.

## HTTP 400

| Code | Retryable | Meaning |
| --- | --- | --- |
| `invalid_request` | No | The request is malformed or missing required fields. |
| `unsupported_file` | No | This file format is not supported. |
| `file_too_large` | No | The file exceeds the maximum size for your plan. |
| `corrupted_file` | No | The file could not be parsed and appears to be corrupted. |
| `encrypted_file` | No | The file is password-protected and cannot be processed. |
| `unsupported_operation` | No | This operation is not available for this file type. |

## HTTP 401

| Code | Retryable | Meaning |
| --- | --- | --- |
| `missing_credentials` | No | No API key was provided. |
| `invalid_api_key` | No | The API key is not valid. |
| `expired_api_key` | No | This API key has expired. |
| `revoked_api_key` | No | This API key has been revoked. |
| `api_key_in_query` | No | API keys must be sent in the Authorization header, never in the URL. |

## HTTP 402

| Code | Retryable | Meaning |
| --- | --- | --- |
| `payment_required` | No | Payment for this organization has failed; processing is paused until it succeeds. |

## HTTP 403

| Code | Retryable | Meaning |
| --- | --- | --- |
| `insufficient_scope` | No | This API key does not have the required scope. |
| `ip_not_allowed` | No | This API key is restricted to a set of IP addresses that does not include this one. |
| `environment_mismatch` | No | A test key cannot access live resources, and vice versa. |
| `organization_suspended` | No | This organization has been suspended. |
| `forbidden` | No | You do not have permission to perform this action. |
| `key_restricted` | No | This API key is not allowed to run this operation. |

## HTTP 404

| Code | Retryable | Meaning |
| --- | --- | --- |
| `not_found` | No | No such resource. |

## HTTP 409

| Code | Retryable | Meaning |
| --- | --- | --- |
| `idempotency_conflict` | No | This Idempotency-Key was already used with a different request body. |
| `upload_session_consumed` | No | This upload session has already been used. |
| `conflict` | No | The resource is in a state that does not allow this operation. |

## HTTP 413

| Code | Retryable | Meaning |
| --- | --- | --- |
| `payload_too_large` | No | The request body is too large. |

## HTTP 422

| Code | Retryable | Meaning |
| --- | --- | --- |
| `malware_detected` | No | The file was rejected because it failed a security scan. |
| `policy_violation` | No | The file violates the acceptable use policy. |
| `validation_failed` | No | The file does not meet the validation policy supplied with the upload. |
| `output_validation_failed` | No | Processing produced output that failed verification, so it was discarded. |
| `unsupported_input` | No | This file is not something the requested operation can process. |

## HTTP 429

| Code | Retryable | Meaning |
| --- | --- | --- |
| `key_spend_limit` | No | This API key has reached its credit spend cap for the current window. |
| `rate_limited` | Yes | Too many requests. Retry after the interval in the Retry-After header. |
| `concurrency_limit` | Yes | Too many jobs are running concurrently for this organization. |
| `credits_exhausted` | No | This organization has no processing credits remaining. |

## HTTP 500

| Code | Retryable | Meaning |
| --- | --- | --- |
| `internal_error` | Yes | An unexpected error occurred on our side. |

## HTTP 503

| Code | Retryable | Meaning |
| --- | --- | --- |
| `processing_unavailable` | Yes | Processing capacity is temporarily unavailable. |
| `dependency_unavailable` | Yes | A required service is temporarily unavailable. |

## HTTP 504

| Code | Retryable | Meaning |
| --- | --- | --- |
| `timeout` | Yes | The operation took too long and was stopped. |
