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

# Authentication

> Authenticate with a personal access token, or the OAuth 2.1 flow for apps acting on a user's behalf.

All requests go to `https://api.hq.zone` over HTTPS. Every endpoint lists the scope it needs under **Authorizations**; HQ uses a `resource:action` scope vocabulary (e.g. `agents:read`, `documents:read`, `conversations:write`, `admin`). A token can never exceed the role of the user it belongs to.

## Personal access tokens (server-to-server)

For backend integrations, authenticate with a **Personal Access Token (PAT)** sent as a bearer token:

```bash theme={null}
curl https://api.hq.zone/v1/api/me \
  -H "Authorization: Bearer hq_pat_..."
```

A workspace admin issues PATs with [Create an API token](/api-reference/tokens/create-token); the secret is shown once at creation. The token's scopes cap what it can do.

<Warning>Treat a PAT like a password — it carries your workspace access. Keep it in a secret manager; never put it in client-side code or version control.</Warning>

## OAuth 2.1 (apps acting for a user)

For apps that act on behalf of a signed-in user (a browser extension, a third-party integration), use the **authorization-code + PKCE** flow:

<Steps>
  <Step title="Register a client">
    Register once via [Dynamic Client Registration](/api-reference/auth/register-client) (RFC 7591), or use a first-party client. Public clients use PKCE and have no secret.
  </Step>

  <Step title="Authorize">
    Send the user's browser to [`/v1/oauth/authorize`](/api-reference/auth/oauth-authorize) with a `code_challenge` (method `S256`). HQ signs the user in and redirects back to your `redirect_uri` with a single-use `code`.
  </Step>

  <Step title="Exchange">
    POST the `code` and `code_verifier` to [`/v1/oauth/token`](/api-reference/auth/oauth-token) (form-encoded) to receive a short-lived access token and a rotating refresh token.
  </Step>

  <Step title="Call the API">
    Use the access token as `Authorization: Bearer ...`. Refresh it at the token endpoint before it expires (\~1 hour); refresh tokens rotate on every use.
  </Step>
</Steps>

The granted scope is what you request intersected with the client's allowed scopes, capped by the user's role. Full details on the [Authentication endpoints](/api-reference/auth/oauth-authorize).

## Verify your token

```bash theme={null}
curl https://api.hq.zone/v1/api/me -H "Authorization: Bearer $HQ_TOKEN"
```

A `200` with your identity confirms the token is valid; a `401`/`403` means it's missing, expired, or lacks the scope.
