API reference

API keys

Programmatic CRUD for mintoken keys. All endpoints under /v1/auth/keys authenticate with a Supabase JWT (the access_token from POST /v1/auth/login), not with a mintoken key. The mintoken key itself is what you use on the proxy endpoints.

Most users don't need this
The dashboard at /dashboard/keys covers every operation here through a UI. These endpoints exist for teams that provision mintoken keys from their own infra (e.g. a CI job that creates a short-lived key per deploy).

Authentication

These endpoints take a Supabase access token, not an mt_live_ key. Get one with POST /v1/auth/login (or pull it out of the Supabase client on the frontend).

Create a key

POST /v1/auth/keys

Returns the raw key string ONCE. The server only stores a hash; if you lose the raw value, rotate the key.

Request body

FieldTypeDefaultNotes
namestring"Default"Must be unique within your active keys. 409 if a name collides.
intensitystring"full""lite" | "full" | "ultra". See Intensity levels.
auto_compress_inputbooleanfalseCompress request prompts in addition to responses. Off by default to avoid surprising callers.
smart_detect_enabledbooleantrueAuto-pick intensity per request based on content. See Smart detection.
context_compressbooleanfalseTier 1 input compression: truncate huge tool results, dedupe repeated file reads. See Context compression.
context_compress_levelstring"standard""conservative" | "standard" | "aggressive".
curl -X POST https://api.mintoken.in/v1/auth/keys \
  -H "Authorization: Bearer <supabase-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production",
    "intensity": "full",
    "auto_compress_input": false,
    "smart_detect_enabled": true,
    "context_compress": false,
    "context_compress_level": "standard"
  }'

# Response (raw_key shown ONCE — save it now):
# {
#   "id": "...",
#   "raw_key": "mt_live_abc123...",
#   "key_prefix": "mt_live_abc1",
#   "name": "Production",
#   "intensity": "full",
#   "auto_compress_input": false,
#   "smart_detect_enabled": true,
#   "context_compress": false,
#   "context_compress_level": "standard",
#   "is_active": true,
#   "created_at": "2026-05-03T...",
#   "last_used_at": null
# }
raw_key returned once
The raw_keyfield is the full mintoken API key. The server stores only a hash. If you don't save it from this response, you cannot recover it; you have to rotate.

List keys

GET /v1/auth/keys

Returns all your active and inactive keys. Only key_prefix is exposed; the full raw key is never returned again.

curl https://api.mintoken.in/v1/auth/keys \
  -H "Authorization: Bearer <supabase-jwt>"

# Response:
# [
#   {
#     "id": "...",
#     "key_prefix": "mt_live_abc1",
#     "name": "Production",
#     "intensity": "full",
#     "auto_compress_input": false,
#     "smart_detect_enabled": true,
#     "context_compress": false,
#     "context_compress_level": "standard",
#     "is_active": true,
#     "rate_limit_rpm": 120,
#     "created_at": "...",
#     "last_used_at": "..."
#   }
# ]

Update key settings

PATCH /v1/auth/keys/{id}

Partial update: send only the fields you want to change. The raw key itself cannot be edited, only its settings (name, intensity, compression flags, etc.).

curl -X PATCH https://api.mintoken.in/v1/auth/keys/<key-id> \
  -H "Authorization: Bearer <supabase-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "intensity": "ultra",
    "smart_detect_enabled": false
  }'

# Any subset of fields can be sent. Omitted fields keep their current value.

Rotate a key

POST /v1/auth/keys/{id}/rotate

Issues a new key with the same settings, then immediately revokes the old one. Use this when a key leaks (commit, log, screenshare).

curl -X POST https://api.mintoken.in/v1/auth/keys/<key-id>/rotate \
  -H "Authorization: Bearer <supabase-jwt>"

# Returns a NEW api key with the same settings. The old key is
# immediately revoked. Deploy the new raw_key everywhere BEFORE
# the old one is revoked, OR you will get a brief 401 window.
Rotation has no soft cutover
The old key returns 401 the instant the rotate response returns. Deploy the new key everywhere before calling rotate, or accept a brief 401 window.

Revoke a key

DELETE /v1/auth/keys/{id}

Soft-delete. Sets is_active = false. The key record is kept so historical usage records still resolve.

curl -X DELETE https://api.mintoken.in/v1/auth/keys/<key-id> \
  -H "Authorization: Bearer <supabase-jwt>"

# Soft delete: is_active = false. Existing requests fail with 401
# the instant this returns.

Plan limits

PlanMax active keys
Free2
Pro10
Team50
Enterprise200

Hitting the limit returns 403 API key limit reached. Revoke an unused key or upgrade.

Errors

StatusMeaning
401 UnauthorizedMissing or invalid Supabase JWT. Refresh and retry.
403 API key limit reachedYou've already created the maximum allowed for your plan.
409 Duplicate nameYou already have an active key with that name. Pick a different one or revoke the existing one first.
404 Not foundThe key id doesn't exist or doesn't belong to you.