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

# Errors

> Error envelope format, status codes, and common error examples

## Error envelope

Every error response follows the same shape:

```json theme={null}
{
  "error": {
    "type": "VALIDATION_ERROR",
    "message": "platform and entity_type query params required",
    "request_id": "req_a1b2c3d4e5f6"
  }
}
```

* **`type`** - a machine-readable error code (e.g., `"VALIDATION_ERROR"`). Use this for
  programmatic error handling.
* **`message`** - a human-readable description of what went wrong.
* **`request_id`** - a unique identifier for this request. Quote this in support requests
  so the team can trace your issue.

## Response headers

Every response (success or error) includes:

| Header         | Description                       |
| -------------- | --------------------------------- |
| `X-Request-ID` | Same value as `error.request_id`  |
| `API-Version`  | Current API version (e.g., `1.0`) |

## Content-Type enforcement

All non-GET requests must include `Content-Type: application/json`. Requests with a
different content type receive a `415 UNSUPPORTED_MEDIA_TYPE` error before reaching the
route handler.

## Error codes

| Code                     | HTTP Status | When it happens                                            |
| ------------------------ | ----------- | ---------------------------------------------------------- |
| `VALIDATION_ERROR`       | 400         | Request body or query params failed schema validation      |
| `AUTHENTICATION_ERROR`   | 401         | Missing, invalid, or revoked API key                       |
| `AUTHORIZATION_ERROR`    | 403         | Valid key but insufficient permissions                     |
| `NOT_FOUND`              | 404         | Entity, mapping, or resource does not exist                |
| `CONFLICT_ERROR`         | 409         | Operation conflicts with existing state                    |
| `UNSUPPORTED_MEDIA_TYPE` | 415         | Request `Content-Type` is not `application/json`           |
| `TRANSFORM_ERROR`        | 422         | Data transformation failed (e.g., missing mapper context)  |
| `RATE_LIMIT_ERROR`       | 429         | Too many requests - currently only on `POST /demo/session` |
| `INTERNAL_ERROR`         | 500         | Unexpected server error - the team is notified             |
| `EXTERNAL_SERVICE_ERROR` | 502         | Upstream service (database) failed                         |

## Examples

### 401 - Invalid API key

```bash theme={null}
curl "$API_BASE/api/v1/connections" \
 -H "Authorization: Bearer sk_demo_invalid_key"
```

```json theme={null}
{
  "error": {
    "type": "AUTHENTICATION_ERROR",
    "message": "Invalid or missing API key",
    "request_id": "req_x9y8z7w6v5u4"
  }
}
```

### 400 - Validation error

```bash theme={null}
curl -X POST "$API_BASE/api/v1/connect" \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer $API_KEY" \
 -d '{"platform": "invalid"}'
```

```json theme={null}
{
  "error": {
    "type": "VALIDATION_ERROR",
    "message": "Invalid input",
    "request_id": "req_m3n4o5p6q7r8"
  }
}
```

### 404 - Entity not found

```bash theme={null}
curl -X POST "$API_BASE/api/v1/propagate" \
 -H "Content-Type: application/json" \
 -H "Authorization: Bearer $API_KEY" \
 -d '{
    "format": "platform",
    "platform": "procore",
    "platform_id": "999999999",
    "entity_type": "payment",
    "data": { "notes": "test" }
  }'
```

```json theme={null}
{
  "error": {
    "type": "NOT_FOUND",
    "message": "Entity mapping not found",
    "request_id": "req_s1t2u3v4w5x6"
  }
}
```
