# Errors (https://docs.propertypixel.app/errors)

Every error code and what to do about it.



Errors use [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) problem details (`application/problem+json`). Branch on `code`, which is stable; `detail` is for people.

```json
{
  "type": "https://docs.propertypixel.app/errors#insufficient_credits",
  "title": "Insufficient credits",
  "status": 402,
  "code": "insufficient_credits",
  "detail": "Insufficient credits",
  "credits_required": 400,
  "credits_available": 120
}
```

| Code                      | Status | Meaning                                                                                                      |
| ------------------------- | ------ | ------------------------------------------------------------------------------------------------------------ |
| `unauthorized`            | 401    | Missing, invalid, expired or revoked credentials. Reconnect the app or use a valid API key.                  |
| `forbidden_scope`         | 403    | The connection is view-only, or your workspace role no longer allows changes.                                |
| `forbidden`               | 403    | You no longer have access to the connection's workspace.                                                     |
| `not_found`               | 404    | The resource doesn't exist in this workspace, or the endpoint doesn't exist.                                 |
| `validation_failed`       | 400    | The input is invalid. `errors` lists each problem with its `path`.                                           |
| `insufficient_credits`    | 402    | Not enough credits. Includes `credits_required` and `credits_available`.                                     |
| `quote_required`          | 409    | The request spends credits. The response includes a `quote`; resend with `quote_id` after the user confirms. |
| `quote_expired`           | 409    | The quote is older than 10 minutes or was already used. Request a new one.                                   |
| `quote_mismatch`          | 409    | The request differs from what was quoted. Request a new quote.                                               |
| `idempotency_conflict`    | 422    | This `Idempotency-Key` was used with a different request.                                                    |
| `idempotency_in_progress` | 409    | The original request with this key is still running. Retry shortly.                                          |
| `conflict`                | 409    | The request conflicts with the current state, for example uploading to a finished upload link.               |
| `rate_limited`            | 429    | Too many requests. Wait `Retry-After` seconds.                                                               |
| `upload_rejected`         | 422    | A photo couldn't be accepted: wrong type, too large, unreachable URL, or the project is full.                |
| `internal`                | 500    | Something went wrong on our side. Retrying with the same `Idempotency-Key` is safe.                          |

Failed jobs are not errors in a response: they appear as jobs with `status: "failed"` and are refunded automatically.
