Authentication
Hexcovery has two kinds of credential, and they live in two different request slots that are never interchangeable.
| Credential | Header slot | Who uses it | Reaches |
|---|---|---|---|
| API key | X-API-Key: <key> |
Agents, CI/CD, scripts, integrations | The programmatic surface (OQL, annotations, heartbeats) + OTLP ingest |
| JWT | Authorization: Bearer <jwt> |
The dashboard, on behalf of a logged-in user | The full dashboard/management API |
The two slots do not overlap. An API key passed in the Authorization: Bearer slot is rejected, and a JWT is not how you authenticate automation. Pick the credential that matches the slot.
API keys (programmatic)
An API key is a long-lived, tenant-scoped credential. It resolves to exactly one organization (your org_id), so every request made with it reads and writes only your data — tenancy is enforced automatically and cannot be widened by the request. Use an API key for anything non-interactive: the Hexcovery agent, an OpenTelemetry SDK, a CI/CD pipeline posting deploy markers, a cron wrapper sending heartbeats, or a script running OQL.
Pass it as the X-API-Key header on every request:
curl -X POST https://server/api/v1/dsl \
-H "X-API-Key: $HEXCOVERY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"SELECT count(*) FROM logs WHERE level = '\''error'\'' LAST 1h"}'
Create, name, and revoke keys from the dashboard — see API keys. Treat a key like a password: store it in a secret manager or environment variable, never commit it to source control.
What an API key can reach
| Endpoint | Method | Reference |
|---|---|---|
/api/v1/dsl |
POST |
Query API |
/api/v1/annotations |
GET, POST |
Annotations API |
/api/v1/annotations/:id |
PUT, DELETE |
Annotations API |
/api/v1/heartbeat/* |
POST |
Heartbeat API |
OTLP ingest :4317 |
gRPC | Sending Data |
Everything else returns 401/403 for an API key — those endpoints require a user session.
JWTs (dashboard sessions)
A JWT is a short-lived access token (15 minutes) the server issues when a user logs in with email + password (and a TOTP code if 2FA is enabled). The dashboard sends it as Authorization: Bearer <jwt> on every request and silently refreshes it. JWTs carry the user identity and role, so they unlock the management surface — dashboards, saved queries, users, teams, org settings, and the built-in pages (overview, hosts, logs, traces, schema discovery).
You do not mint JWTs yourself for integrations. If a task can be done with an API key, use the API key; the dashboard-only endpoints are not part of the public programmatic contract and may change.
Choosing
- Building an integration, a script, or a pipeline? Use an API key in
X-API-Key. Stay on the programmatic surface. - Driving the UI as a user? That's a JWT, handled for you by the dashboard.