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

# Authentication

> Bearer key auth, and why your API key must never leave your server.

All requests require an `Authorization` header:

```
Authorization: Bearer <CXH_API_KEY>
```

To request a key, email
[partners@collectivex.health](mailto:partners@collectivex.health). Keys have
the form `cxh_pk_live_*`.

A missing, malformed, or invalid key returns `401 unauthorized`. A valid key
without permission for an operation returns `403 forbidden` — contact
[partners@collectivex.health](mailto:partners@collectivex.health) if you hit
that unexpectedly.

## API keys are server-side only

> [!WARNING]
>
> Do NOT call `/v1/query` or `/v1/chat` directly from a browser.
> Build a server-side proxy (a Next.js Route Handler, Express middleware, or
> Lambda function) that forwards requests and authenticates with the partner
> key from a secret manager. Browser-direct usage will leak the key to your
> users.

The recommended integration pattern:

```
Browser  →  useChat({ api: '/api/proxy/chat' })
              ↓
Partner's server-side proxy (your Route Handler / Lambda)
              ↓  Authorization: Bearer $CXH_API_KEY (from env)
POST https://api.collectivex.health/v1/chat  (or /v1/query)
```

Your app owns end-user identity. We never receive end-user PII. The partner
key is shared across all of your end-users; you take the contract that no
PHI is forwarded to us in prompts.

## Native mobile apps: short-lived session tokens

The server-side rule above is absolute for browsers and does not change.
For a **native mobile app** there is a second sanctioned pattern: your
backend presents the long-lived key to `POST /v1/session-tokens` and hands
the returned short-lived, scoped key straight to the app, which then calls
`/v1/query` and `/v1/chat` directly. A session key expires after at most
60 minutes, carries a total request allowance (`max_requests`), can only
reach `/v1/query` and `/v1/chat`, and can never mint further session keys.
The long-lived key itself still never leaves your server.

See the **Session tokens** operation in the API Reference tab for the
request and response shapes, and the "Mobile-direct access" section of the
API introduction for a runnable mint-then-use example.

## Example proxy

Point your client at YOUR own proxy, never at `api.collectivex.health`
directly:

```tsx theme={null}
'use client';
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';

export function ResearchChat() {
  const { messages, sendMessage } = useChat({
    transport: new DefaultChatTransport({
      api: '/api/proxy/chat',   // YOUR proxy — NOT api.collectivex.health
    }),
  });
  // ... render
}
```

Your server-side proxy holds the `CXH_API_KEY` and forwards to `/v1/chat`:

```typescript theme={null}
// app/api/proxy/chat/route.ts
import 'server-only';
export const runtime = 'nodejs';
export const maxDuration = 60;

export async function POST(req: Request) {
  const CXH_API_KEY = process.env.CXH_API_KEY;
  if (!CXH_API_KEY) return new Response('CXH_API_KEY not configured', { status: 500 });

  const upstream = await fetch('https://api.collectivex.health/v1/chat', {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      authorization: `Bearer ${CXH_API_KEY}`,
    },
    body: await req.text(),
  });
  return new Response(upstream.body, {
    status: upstream.status,
    headers: upstream.headers,
  });
}
```

The same pattern applies to `/v1/query` — the proxy pipes
bytes through unchanged, so streaming from `/v1/chat` works without any
special handling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.