Authentication
The header schemes for tenant, end-user, and proxy-mode API access.
Credential types
| Scheme | Header(s) | Acts as |
|---|---|---|
| Tenant API key | X-API-Key: tk_… (or Authorization: Bearer tk_…) | Your tenant |
| Proxy-mode end user | X-API-Key: tk_… + X-End-User: <your-user-id> | A specific end user, asserted by your backend |
| Platform end user | Authorization: Bearer <jwt> | An end user who signed in via /auth/login or OAuth |
An optional X-Space-Id header selects a specific space; without it the user's default space is used.
Whatever the scheme, it resolves to a principal (tenant · user · space) and the database session is scoped to that identity with Postgres row-level security — so isolation is enforced below the API, not by application code.
Which one should I use?
- Server-to-server integration (your product drives conversations): use proxy mode. Your backend holds the tenant key and asserts the end-user identity per request — users never see the key.
- Your own client apps where users log in to the platform directly: use end-user JWTs.
- Administrative automation (managing documents, agents, usage): use the plain tenant key against the management endpoints.
The tenant API key is a server-side secret. Never ship it in browser code or mobile apps — for browser scenarios use the embeddable widget, which authenticates through share tokens instead.
Proxy mode example
curl https://chat.agent4.io/chat \
-H "X-API-Key: tk_live_…" \
-H "X-End-User: crm-user-8841" \
-H "Content-Type: application/json" \
-d '{ "message": "What documents do I need for a refinance?" }'The end-user id is any stable identifier from your system. The platform creates the user and their default space on first sight, and scopes all history, memory, and documents to them.
Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid credentials |
403 | Valid identity, but no access to the requested space/agent |
429 | Monthly token quota exhausted |