> ## 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.

# Authentication

> API key modes, rate limits, and CORS

Every authenticated endpoint requires a Bearer token in the `Authorization` header:

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

## Key modes

Structural uses three API key modes, distinguished by prefix:

| Prefix     | Mode       | How to get one                                                                                    |
| ---------- | ---------- | ------------------------------------------------------------------------------------------------- |
| `sk_demo_` | Sandbox    | Instantly via `POST /api/v1/demo/session`                                                         |
| `sk_test_` | Staging    | Issued during customer onboarding - email [support@structural.app](mailto:support@structural.app) |
| `sk_live_` | Production | Issued during customer onboarding - email [support@structural.app](mailto:support@structural.app) |

All three modes go through identical Bearer authentication. The prefix tells you which
environment the key targets, not a difference in behavior or permissions.

### Key lifecycle

* Keys are **SHA-256 hashed at rest** and returned exactly once at creation. There is no
  retrieval endpoint - capture your key immediately.
* Demo keys (`sk_demo_*`) are ephemeral. They are revoked when you call
  `DELETE /api/v1/demo/session`.
* Production and staging keys (`sk_live_*`, `sk_test_*`) are provisioned during customer
  onboarding by the Structural team.

### Error responses

Missing or invalid keys return `401`:

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

## Rate limits

`POST /api/v1/demo/session` is rate-limited to **5 requests per IP per minute**. Exceeding
this returns `429 RATE_LIMIT_ERROR`.

Other endpoints have no enforced rate limit today, but usage is subject to fair-use
expectations. Sustained high-volume usage requires a production key with limits negotiated
during customer onboarding.

## CORS

The API restricts allowed origins via a server-side `CORS_ORIGIN` configuration. Browser
consumers should expect CORS preflights to fail unless their origin is whitelisted.

To get your domain added to the allowed origins list, contact
[support@structural.app](mailto:support@structural.app) during onboarding.

## Content-Type

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. Every curl example in these docs includes the header explicitly.

## Response headers

Every response includes:

| Header         | Description                                                                           |
| -------------- | ------------------------------------------------------------------------------------- |
| `X-Request-ID` | Unique request identifier (e.g., `req_a1b2c3d4e5f6`). Quote this in support requests. |
| `API-Version`  | Current API version (e.g., `1.0`).                                                    |
