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

# Authentication

> Every client request carries a bearer token.

Send your API key as a bearer token on every request:

```bash theme={null}
curl "$BASE/v1/async/task/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"
```

A missing or wrong key returns `401`:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key",
    "timestamp": "2026-07-09T04:12:00.000Z"
  }
}
```

## Which endpoints require it

| Endpoint                    | Auth                   |
| --------------------------- | ---------------------- |
| `POST /v1/async/task`       | Bearer                 |
| `POST /v1/async/task/batch` | Bearer                 |
| `GET /v1/async/task/{id}`   | Bearer                 |
| `GET /stats`                | Bearer                 |
| `GET /capacity`             | Bearer                 |
| `GET /health`               | None — liveness probe  |
| `GET /ready`                | None — readiness probe |

<Note>
  The service also exposes `/internal/*` routes used by its own Pub/Sub push subscription
  and Cloud Scheduler jobs. They authenticate with a separate internal token, are not part
  of the client contract, and are not documented here.
</Note>

## Key management

There is a single static token shared by all clients. It lives in Google Secret Manager
under `pplx-server-api-key` and is compared verbatim by the server.

To rotate, add a new secret version and redeploy so the service picks it up:

```bash theme={null}
KEY=$(openssl rand -base64 32)
printf '%s' "$KEY" | gcloud --project=anymorph-prompting \
  secrets versions add pplx-server-api-key --data-file=-
```

<Warning>
  Rotation is not zero-downtime. The server accepts exactly one key at a time, so clients
  must cut over as the new revision rolls out. If you need overlapping validity, the server
  must first be changed to accept a comma-separated key list.
</Warning>

Reading the secret requires `roles/secretmanager.secretAccessor` scoped to
`pplx-server-api-key`.
