# Errors

> Every error code the Gomry Cloud API returns, what causes it, whether it is retryable, and whether the failed request was billed.

Source: https://cloud.gomry.com/docs/errors

Errors are JSON, with a stable machine-readable `error` code and a human `message`. Branch on the code — the message is written for a person and may be reworded.

## The shape

```json
{
  "error": "api_not_enabled",
  "message": "scrape is not enabled for this project. Enable it in the console."
}
```

The `x-request-id` header is present on errors too, including on a `500`. Capture it — without it a report of an intermittent failure cannot be traced back to the request that produced it.

## Codes

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `validation_error` | The body failed schema validation. The response does not echo your input. |
| 401 | `unauthorized` | Key missing, malformed, unknown, revoked or expired. |
| 403 | `forbidden` | The key is valid but lacks the scope for this operation. |
| 403 | `api_not_enabled` | The project has not enabled this API. |
| 404 | `not_found` | The addressed resource does not exist, or is not yours to see. |
| 409 | `conflict` | The request conflicts with the current state — a name already taken, for example. |
| 402 | `billing_required` | The organization has no payment method. Add a card. |
| 402 | `billing_past_due` | The last invoice could not be collected. Update the card. |
| 402 | `billing_suspended` | Billing is suspended. Contact support. |
| 402 | `insufficient_credit` | The project reached its monthly budget cap. |
| 429 | `rate_limited` | Too many requests for this key. Back off and retry. |
| 502 | `upstream_error` | A provider we depend on failed. |
| 503 | `provider_unavailable` | The service is not currently configured to serve. Retry. |
| 500 | `internal_error` | A fault on our side. Retry, and send us the request id. |

Individual services add codes of their own for a failure that is specific to them — `scrape_failed` and `fetch_failed` are both `502` and both mean the page could not be retrieved. They are documented on each [service's page](https://cloud.gomry.com/services).

## What a failure costs

> **Note:** Only work that produced a result is billed. A validation error, an auth failure, a rate limit, a timeout, or an upstream failure costs nothing.

Failed requests are still recorded, so they appear in your usage dashboard with their status — you can see a spike of `429`s without being charged for it. The quantity billed is what the handler actually consumed, which is why a partially successful call (an extraction that needed a retry) reports exactly what it used in the response body.

## Retrying

- Retry `429`, `500`, `502` and `503` with exponential backoff and jitter.
- Do not retry `400`, `401` or `403` — the same request will fail identically until you change something.
- Do not retry `402` in a loop. It means spending is blocked until a human adds a card, fixes one, or raises a budget.
- Retries are billed like any other request: a successful retry of a failed call is one billable unit, because the failed attempt was free.
