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

# Authentication

> How to pass your API key, what errors to expect, and what the rate limit is.

Every `/v1/ltl/*` and `/v1/abc/*` endpoint requires an `X-API-Key` header. Keys are issued through [RapidAPI](https://rapidapi.com/ladourv) in the MVP phase — the same key works whether you call RapidAPI's gateway or `api.nexusfeed.dev` directly.

## Header format

```http theme={null}
X-API-Key: <your-api-key>
```

Keys are 32+ URL-safe characters, prefixed with a `live_` or `test_` tag depending on environment. Plaintext keys are shown exactly once, at creation time. NexusFeed stores only the SHA-256 hash — if you lose the key, you must rotate it.

<Warning>
  Never commit keys to git. For local development, keep them in a `.env` file. For production, inject via the environment variable convention your platform uses (`MCP_API_KEY`, `NEXUSFEED_API_KEY`, `X_API_KEY` — pick one).
</Warning>

## Product scoping

A single key may be scoped to LTL only, ABC only, or both. If your key only has LTL access and you call `/v1/abc/search`, you'll get:

```json theme={null}
{
  "detail": {
    "error": "PRODUCT_NOT_ENABLED",
    "message": "This API key does not have access to the abc product"
  }
}
```

Status code: `403`. Fix: subscribe to the other product's RapidAPI listing.

## Rate limit

The default limit is **60 requests per minute per tenant**, enforced with a Redis fixed-window counter. Exceeding it returns `429 Too Many Requests`:

```json theme={null}
{
  "detail": {
    "error": "RATE_LIMITED",
    "message": "Rate limit exceeded: 60 requests per minute"
  }
}
```

If you need a higher limit for production traffic, ask — limits are per-tenant and adjustable without touching code.

<Note>
  The rate limiter **fails open**. If Redis is unreachable, requests pass through unthrottled rather than blocking availability. This is a deliberate trade-off to keep the API up during infrastructure incidents.
</Note>

## Error contract

All errors return a JSON body with an `error` code and a human-readable `message`.

| Status | Error code                      | Meaning                                                                                |
| ------ | ------------------------------- | -------------------------------------------------------------------------------------- |
| `401`  | `UNAUTHORIZED`                  | Missing, malformed, or inactive API key                                                |
| `403`  | `PRODUCT_NOT_ENABLED`           | Key does not have access to the requested product (LTL vs ABC)                         |
| `404`  | `NOT_FOUND`                     | Carrier code, state code, or license number not supported                              |
| `422`  | `MISSING_PARAMS`                | At least one of `dba_name`, `owner_name`, or `address` is required on `/v1/abc/search` |
| `429`  | `RATE_LIMITED`                  | Rate limit exceeded                                                                    |
| `503`  | `SOURCE_UNAVAILABLE`            | Upstream source returned an error or extraction failed                                 |
| `503`  | `CAPTCHA_SOLVER_NOT_CONFIGURED` | TX TABC requires server-side 2Captcha configuration                                    |

## Security notes

* Every response includes a `request_id` in the `X-Request-ID` response header. Quote it in support requests.
* Usage is logged server-side for 13 months to a Redis sorted set keyed by tenant ID. This enables monthly billing reconciliation and abuse investigation — we do not log request *contents*, only method, path, and status.
* The plaintext API key is **never** retrievable after creation. If you lose it, rotate it via the `/v1/admin/keys` endpoint (private admin API) or through RapidAPI's dashboard.
