> ## Documentation Index
> Fetch the complete documentation index at: https://developers.beta.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 isn't a valid UUID (path or request-body ID). Some endpoints (e.g. funds) take a numeric ID and also return this code | Entity routes take a UUID, e.g. `/data/entities/{uuid}`; numeric IDs are rejected there. For funds and similar, use the numeric ID                |
| `UNKNOWN_FILTER`          | `400`     | Filter key isn't registered for the scope                                                                                       | See the [Filters reference](/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 is invalid — wrong type, or (for enum filters) not in the accepted value set                                       | Check the value type in the [Filters reference](/references/filters-and-sorting); for enums, look values up via `/reference/filters/{key}/values` |
| `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](/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](/concepts/aggregates)                                               |

## Common scenarios

### Invalid filter expression

```bash theme={null}
curl -g "https://api.beta.dealroom.app/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" }
  }
}
```

### Invalid enum value

Enum filters (`round_type`, `preferred_round`, `investor_type`, `article_type`) accept a
closed, case-insensitive value set. An unknown value returns `400` rather than an empty
result — discover valid values via `/reference/filters/{key}/values`.

```bash theme={null}
curl -g "https://api.beta.dealroom.app/data/transactions?filter=round_type[eq]:seriesa" ...
```

```json theme={null}
{
  "error": {
    "code": "FILTER_VALIDATION_ERROR",
    "message": "Invalid value for filter 'round_type': \"seriesa\". See /reference/filters/round_type/values for accepted values.",
    "details": { "filter": "round_type" }
  }
}
```

### 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](/getting-started/quickstart). The SDK snippets in the
[Authentication](/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](/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.
