linq uses API keys as the only principal — there are no user accounts, sessions, or cookies. Every request to the REST API must carry a valid key, and every key carries a name, a role (expressed as a set of CASL claims), an optional expiry, and nothing else. Authenticating a request is a single indexed lookup against theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/org-quicko/linq/llms.txt
Use this file to discover all available pages before exploring further.
api_keys table: no joins, no session store, no external identity provider.
Obtaining Your First Key
When linq starts against a database with an emptyapi_keys table, it mints one admin key automatically and prints it to stdout exactly once:
Key Format
Every linq API key is produced bygenerateKey() in apps/server/src/auth/keys.ts:
linq_ prefix followed by 43 base64url characters — 48 characters total. The first 12 characters of the full key (e.g. linq_XXXXXXX) are stored as a human-readable prefix field so keys can be told apart in listings without exposing the secret. The raw key value itself is never stored or returned after the creation response.
Passing the Key in Requests
linq’s authentication middleware (auth/middleware.ts) accepts the key via two headers, checked in this order:
Option 1 — Authorization: Bearer (preferred)
X-Api-Key
Authorization: Bearer when your HTTP client or SDK already manages Bearer tokens; use X-Api-Key when it is more convenient to set a custom header. A request with no key, an unrecognised key, or an expired key receives a 401 Unauthorized response.
Creating Additional Keys
- CLI
- API
Use
The raw key is printed once and never stored. Record it before the command exits.
key:create to mint a new key without restarting the server. This is the
same code path the API and the Keys UI page use.| Flag | Default | Description |
|---|---|---|
--name | (required) | Human-readable label for the key (1–100 chars) |
--preset | admin | Role preset: viewer, editor, or admin |
--expires | (none) | ISO 8601 expiry timestamp, e.g. 2026-01-01T00:00:00Z |
Key Fields
Every key returned by the API includes the following fields. Note thatsecret only appears in the creation response (ApiKeyCreated type); all other responses return the ApiKey shape without it.
UUIDv7 identifier. Stable and used in all key management endpoints.
Human-readable label set at creation time. Mutable via
PATCH /api/v1/keys/{id}.The expanded list of
{ action, subject } pairs that define what this key can
do. Always stored and returned as the full claim set, even when created with a
preset shorthand.The convenience label (
viewer, editor, admin) if the key’s claims exactly
match a known preset; null for custom claim sets. Computed at read time, not
stored.The first 12 characters of the raw key (e.g.
linq_XXXXXXX). Stored for
identification purposes in the UI and API listings without revealing the secret.ISO 8601 expiry timestamp, or
null if the key never expires.ISO 8601 timestamp of when the key was created.
ISO 8601 timestamp of the most recent update to the key.
Listing Keys
GET /api/v1/keys returns a paginated list of all keys. Keys with the admin
preset (i.e. the create Key claim) receive the full ApiKey shape in the
response; keys without it receive a reduced ApiKeySummary (id, name, claims,
preset only) — enough to identify a key, but not enough to manage others.
The Keys page in the linq Client UI provides a visual listing of all keys and
links directly to creation and revocation flows, backed by the same
GET /api/v1/keys and POST /api/v1/keys endpoints.Revoking a Key
SendDELETE /api/v1/keys/{id} to permanently delete a key. The operation is
irreversible — there is no soft-delete or archive state for keys.
204 No Content. A key cannot revoke itself — the server returns 403 Forbidden if {id} matches the key making the request.
Links created by a revoked key are not affected. Links carry no reference
to the key that created them (see
docs/adr/0016 in the source repo). Revoking
an editor’s key never deletes, archives, or alters any link that editor
created.Rotating a Key
linq has no in-place rotation endpoint. To rotate a key:Create a replacement key
Use
POST /api/v1/keys or bun run key:create to mint a new key with the
same name and preset as the one being replaced.Update all consumers
Deploy or reconfigure every service or integration that uses the old key to
use the new one.
Key Expiry
Setexpires_at to an ISO 8601 timestamp when creating or updating a key. Once
that timestamp has passed, any request carrying that key receives 401 Unauthorized
with the message "API key has expired" — even if the row still exists in the
database.
PATCH /api/v1/keys/{id} with
"expires_at": null.