# Integrate with Headless

External servers call Zagger through the Headless API. Scopes used on data routes include `chat`, `ingest`, `data:read`, and `yuml:read`. A missing or invalid bearer token is HTTP 401. A token without the route's scope is HTTP 403.

1. An admin creates an integration in the product (Headless → Integrations) and stores `client_id` and `client_secret` on your server. The secret is shown once and is never written into these public docs.
2. `POST /casc/v1/headless/v1/token` with `client_id`, `client_secret`, and `sub_user` returns a bearer access token. That exchange is the only Headless call that accepts the secret. Later calls send `Authorization: Bearer`.
3. `POST /casc/v1/headless/v1/chat/send` with the bearer token and the message. Then `GET /casc/v1/headless/v1/chat/requests/{requestId}/wait` or `/result` for the reply.
4. Research jobs are read by id: `GET /casc/v1/headless/v1/research/jobs/{jobId}` and `.../report`. Do not ask chat to look up a job id.
5. Horizon rows are `GET /casc/v1/headless/v1/rest` with `data:read`. Do not send the Headless JWT to Supabase `/rest/v1`.

The contract without examples of live keys is `/openapi-headless.json`. Human help is `/docs/headless.md` (and `/docs/headless.html`).
