> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thedatacity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Status codes, the problem-details response shape, and the failure that does not return an error at all.

The API uses standard HTTP status codes. Error bodies follow
[RFC 9457 problem details](https://www.rfc-editor.org/rfc/rfc9457), so they share the same field
names wherever they come from.

## The failure that is not an error

Read this before the status code table, because it is the problem most integrations hit first.

A filter value the market does not recognise does **not** return an error. It returns `200` with an
empty result, exactly as a valid filter matching no companies would.

```json theme={null}
{ "Companies": [], "TotalCount": 0 }
```

A typo in a classification code, a US state name sent to France, or a filter key that market does
not have all produce that same response. Nothing in it tells you the request was wrong.

<Warning>
  Call `GET /filters` for the market and use the values it returns. Do not guess codes, and do not
  copy them between markets — the classification schemes and location filters differ per country.
  See [Compare markets](/global-api/index) for what changes.
</Warning>

If a query returns nothing and you expected results, check your filter values against `/filters`
before assuming the data is missing.

## Status codes

| Status | When to expect it                                                                                | What to do                                                                                 |
| ------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `200`  | Request succeeded. An empty result set is still a `200`.                                         | Process the body. If it is empty and you expected records, check your filter values.       |
| `400`  | Malformed request — bad JSON, or a parameter of the wrong type.                                  | Read `detail` and fix the request.                                                         |
| `401`  | No API key, or a key that is not valid.                                                          | Check the `Authorization` header. See [Authentication](/global-api/guides/authentication). |
| `404`  | Unknown path, unknown market code, a wrong HTTP method, or a company number that does not exist. | Check the path, the market code and the method. Only `us`, `fr`, `de` and `ie` are valid.  |
| `422`  | Well-formed request the service cannot process, such as mutually exclusive filters.              | Read `detail` and adjust the body.                                                         |
| `429`  | Over the rate limit.                                                                             | Wait for `retry-after`. See [Rate limits](/global-api/guides/rate-limits).                 |
| `500`  | Unexpected server error.                                                                         | Retry with backoff. If it persists, contact support with the request ID.                   |

## Response shape

Errors come from one of two places, and the difference shows up in the `content-type`.

### Rejected at the gateway

Requests that never reach the data service are answered by the gateway: `401`, `429`, and the `404`
you get from an unknown path, an unknown market code or a wrong HTTP method. These carry
`content-type: application/problem+json` and include a `trace` object:

```json theme={null}
{
  "type": "https://httpproblems.com/http-status/401",
  "title": "Unauthorized",
  "status": 401,
  "detail": "No Authorization Header",
  "instance": "/v1/us/companies",
  "trace": {
    "timestamp": "2026-07-30T10:18:35.786Z",
    "requestId": "c73bf67a-8f05-42e7-bee7-bf84094b4b9a",
    "buildId": "dbc65d42-8f18-4149-bf68-b85466262259",
    "rayId": "a2339ec59d67a62f-MAN"
  }
}
```

### Returned by the data service

A request that routes correctly but the service cannot fulfil returns `400`, `422`, `500`, or a
`404` for a company number that does not exist. These carry `content-type: application/json` and the
same problem-details fields, without the `trace` object:

| Field      | Type    | Meaning                                     |
| ---------- | ------- | ------------------------------------------- |
| `type`     | string  | URI identifying the kind of problem.        |
| `title`    | string  | Short summary of the problem type.          |
| `status`   | integer | The HTTP status code, repeated in the body. |
| `detail`   | string  | What went wrong with this specific request. |
| `instance` | string  | The path that produced the error.           |

Individual fields can be absent. Read `status` from the HTTP response rather than the body.

<Note>
  `500` responses may have no body at all. Do not assume an error response is parseable JSON —
  check the status code first, then the content type.
</Note>

## Reporting a problem

When contacting [support@thedatacity.com](mailto:support@thedatacity.com), include the
`trace.requestId` if the response had one, or the timestamp and full request path if it did not.
That identifier lets us find the exact request in our logs.

Do not send us your API key.

## Handling errors in code

Treat `429` and `500` as retryable, and everything else in the `4xx` range as a request you need to
fix:

```python theme={null}
response = requests.post(url, headers=headers, json=body, timeout=60)

if response.status_code == 429:
    ...  # wait for retry-after, then retry
elif response.status_code >= 500:
    ...  # retry with exponential backoff
elif response.status_code >= 400:
    problem = response.json()
    raise ValueError("%s: %s" % (problem.get("title"), problem.get("detail")))

companies = response.json()["Companies"]
```

The `detail` field is written for developers, not end users. Its wording can change between
releases, so log it rather than displaying it in your own interface.
