Skip to content

API keys (personal access tokens)

DataQ can mint you a personal access token (PAT) — a long-lived, revocable credential for scripts, CI, and always-on MCP clients, where an SSO browser flow or a ~60-minute Azure AD token doesn't fit (ADR 0026).

A PAT authenticates as you: it inherits exactly your per-suite access (view < edit < admin < owner) on the REST API and /mcp alike. There is no separate "API-key permission model" to configure — if you can see a suite in the web app, your key can; if you can't, it can't.

Minting a key

POST /api/v1/me/api-keys (any authenticated caller — including an existing PAT):

curl -sS -X POST "$DATAQ_URL/api/v1/me/api-keys" \
  -H "Authorization: Bearer $AZURE_AD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-smoke", "expires_in_days": 90}'

The response carries the plaintext token exactly once:

{
  "id": "…",
  "name": "ci-smoke",
  "key_prefix": "dq_live_AbCd",
  "expires_at": "2026-10-02T09:00:00Z",
  "token": "dq_live_…"
}

Store it now — it cannot be retrieved again

Only a hash is kept at rest. If the token is lost, revoke the key and mint a new one. Never commit a token to version control; put it in your CI secret store / Key Vault.

  • name — a label for telling keys apart (e.g. ci-smoke, mcp-desktop).
  • expires_in_days — default 90, maximum 365. Non-expiring keys are not supported.

Using a key

The token goes wherever an Azure AD bearer would — same header, same endpoints:

curl -sS "$DATAQ_URL/api/v1/suites" -H "Authorization: Bearer dq_live_…"

For MCP clients, use it in place of the short-lived browser token in your client config (see AI assistants (MCP setup)) — no more re-pasting on 401s until the key expires.

Listing and revoking

curl -sS "$DATAQ_URL/api/v1/me/api-keys" -H "Authorization: Bearer …"
curl -sS -X DELETE "$DATAQ_URL/api/v1/me/api-keys/<key_id>" -H "Authorization: Bearer …"

Listing returns metadata only (name, prefix, expiry, last-used) — never the token. Revocation (DELETE, 204) is immediate and idempotent: the key stops authenticating on its next request. Mint one key per integration so revoking one doesn't break the others.

Security properties

Property Behaviour
At rest SHA-256 hash only; the plaintext is never stored or logged (prefix only)
Show-once Plaintext appears solely in the creation response
Expiry Mandatory (≤ 365 days); expired keys stop authenticating. The panel shows Expires in Nd for the last two weeks of a key's life (#838) — a status that reads Active until the instant it reads Expired is a warning that arrives after the breakage
Revocation Immediate, per-key, idempotent
Failure mode Unknown, revoked, and expired keys all return the same 401 — no probing oracle
Owner lifecycle Deleting/deactivating a user kills their keys with them
Last used last_used_at tracked (coarse-grained) for spotting stale keys