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

# Errors

> How the Dealroom API surfaces errors — response envelope, canonical error-code catalog, and common scenarios with example responses.

When a request fails, the Dealroom API returns a JSON envelope with a consistent shape and
an HTTP status code. Error codes are stable strings — switch on `error.code` in your client
rather than parsing the human-readable `message`.

## Response envelope

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human-readable description of what went wrong",
    "details": { "filter": "launch_date" }
  }
}
```

| Field     | Description                                                                                                                                                              |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `code`    | Stable identifier — use this for programmatic error handling                                                                                                             |
| `message` | Human-readable explanation. Safe to surface in dev tools, but the exact wording may change                                                                               |
| `details` | Optional extra context. May be absent, an object (e.g. `{ "filter": "launch_date" }`), or an array of `{ "path", "message" }` entries for schema-validation (422) errors |

## Error-code catalog

| Code                      | HTTP      | When it happens                                                                                  | How to fix                                                                                                   |
| ------------------------- | --------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `VALIDATION_ERROR`        | `400/422` | Missing/invalid header (`400`) or request body/parameter fails OpenAPI schema validation (`422`) | Inspect `message` and `details` for the offending field, correct, retry                                      |
| `INVALID_ENTITY_ID`       | `400`     | Entity ID in the path isn't a number                                                             | Use a numeric ID, e.g. `/api/data/entities/12345`                                                            |
| `UNKNOWN_FILTER`          | `400`     | Filter key isn't registered for the scope                                                        | See the [Filters reference](/mintlify/references/filters-and-sorting) for available filters per scope        |
| `FILTER_PARSE_ERROR`      | `400`     | Filter expression has a syntax error                                                             | Check `and()` / `or()` parentheses and the `field[op]:value` form                                            |
| `FILTER_VALIDATION_ERROR` | `400`     | Filter value doesn't match the expected type                                                     | Check the filter's value type in the [Filters reference](/mintlify/references/filters-and-sorting)           |
| `UNSUPPORTED_OPERATOR`    | `400`     | Operator not allowed for that filter                                                             | Use one of the operators listed in `message`                                                                 |
| `UNAUTHORIZED`            | `401`     | Missing or invalid Bearer token                                                                  | Re-fetch a token via [Authentication](/mintlify/getting-started/authentication)                              |
| `FORBIDDEN`               | `403`     | Token is valid but lacks the required permission                                                 | Check your API key's scope list in **Settings > API**                                                        |
| `NOT_FOUND`               | `404`     | Resource ID doesn't exist or isn't visible to your key                                           | Verify the ID; check permissions if the entity exists in another dataset                                     |
| `INTERNAL_SERVER_ERROR`   | `500`     | Unclassified server-side failure                                                                 | Retry with backoff. If persistent, contact support with the response payload                                 |
| `DATABASE_ERROR`          | `500`     | Database query failed (e.g. constraint violation)                                                | Retry. If persistent, contact support                                                                        |
| `SCHEMA_ERROR`            | `500`     | Database schema mismatch (internal)                                                              | Should never reach clients; contact support if you see one                                                   |
| `EXTERNAL_SERVICE_ERROR`  | `502/503` | Downstream service unavailable (currently Auth0 Management API)                                  | Retry with backoff                                                                                           |
| `QUERY_TIMEOUT`           | `504`     | Query exceeded the 15-second execution budget                                                    | Narrow the query: add filters, reduce `limit`, or use an [aggregate endpoint](/mintlify/concepts/aggregates) |

## Common scenarios

### Invalid filter expression

```bash theme={null}
curl "https://api-next.dealroom.co/api/data/entities?filter=launch_date[invalid_op]:2020" ...
```

```json theme={null}
{
  "error": {
    "code": "UNSUPPORTED_OPERATOR",
    "message": "Operator 'invalid_op' not supported for filter 'launch_date'. Allowed operators: eq, neq, gt, gte, lt, lte",
    "details": { "filter": "launch_date" }
  }
}
```

### Missing required header

The API requires `Authorization` on every authenticated request. API-key (M2M)
requests additionally require `X-Client-Id` set to the key's `client_id`. The
status code depends on which header is missing:

* **Missing `Authorization`** → `401 UNAUTHORIZED`
* **Missing `X-Client-Id` on an M2M request** → `400 VALIDATION_ERROR`

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "X-Client-Id header is required for API key requests"
  }
}
```

### Expired token

After your `access_token` expires (default 24h):

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Token has expired"
  }
}
```

Refresh the token via the OAuth2 client-credentials flow — see the
[Quickstart](/mintlify/getting-started/quickstart). The SDK snippets in the
[Authentication](/mintlify/getting-started/authentication) guide handle this automatically.

### Query timeout

A heavy aggregate or unfiltered list query may exceed the 15-second execution budget:

```json theme={null}
{
  "error": {
    "code": "QUERY_TIMEOUT",
    "message": "Query took too long to execute (15s timeout)"
  }
}
```

Narrow the query (add filters, reduce `limit`) or switch to a purpose-built
[aggregate endpoint](/mintlify/concepts/aggregates) instead of paging through raw entities.

## Handling errors

Switch on `error.code` — it's stable across API versions. Messages may change for clarity.

```typescript theme={null}
try {
  const { data } = await dealroom.get("/entities", { params });
  return data;
} catch (err) {
  const code = err.response?.data?.error?.code;

  switch (code) {
    case "UNAUTHORIZED":
      // Refresh the token and retry
      break;
    case "QUERY_TIMEOUT":
      // Narrow the query (more filters, smaller limit) or use an aggregate endpoint
      break;
    case "VALIDATION_ERROR":
    case "UNKNOWN_FILTER":
    case "FILTER_VALIDATION_ERROR":
    case "UNSUPPORTED_OPERATOR":
    case "FILTER_PARSE_ERROR":
    case "INVALID_ENTITY_ID":
      // Bug in your request — surface to your dev team
      break;
    case "NOT_FOUND":
      // Expected for some lookups; handle as a business case
      break;
    default:
      // 5xx — retry with exponential backoff
  }
}
```

<Tip>
  Treat the `message` field as informative, not contractual. Always switch on `code`.
</Tip>

## Endpoint-specific errors

Each endpoint may return a subset of these codes plus endpoint-specific ones. See the
[API Reference](/api-reference) for the catalog per endpoint.
