API Reference
OIDC
Platform

End-user API keys

AdminUpdated Sep 11, 2026

End-user API keys

Distinct from your instance's sk_/pk_ keys: your tenant can mint API keys for its own users and organizations (so your customers can script your product), then ask Atlas to verify a presented key. Only a hash is stored — the ak_ secret is shown exactly once at mint.

{
  "object": "api_key",
  "id": "apikey_…",
  "subject_type": "user",
  "subject_id": "user_2a…",
  "name": "CI token",
  "prefix": "ak_live_ab12",
  "claims": { "scope": "read" },
  "last_used_at": null,
  "expires_at": null,
  "revoked_at": null,
  "created_at": 1757600000000
}

Endpoints

Method & path

Scope

Notes

GET /v1/api_keys

api_keys:read

List (optionally narrowed by subject_type/subject_id). Never the secret.

POST /v1/api_keys

api_keys:write

Mint for a user or organization. Returns the ak_ secret once.

POST /v1/api_keys/verify

api_keys:read

Verify a presented secret. Rate-limited.

GET /v1/api_keys/:id

api_keys:read

Prefix + metadata, never the secret

PATCH /v1/api_keys/:id

api_keys:write

Update name, claims, or expiry

DELETE /v1/api_keys/:id

api_keys:write

Revoke; stops verifying immediately (record kept)

Mint & verify

// Mint — capture the secret now; it is never shown again
const key = await atlas.apiKeys.create({
  subject_type: 'user',
  subject_id: 'user_2a',
  name: 'CI token',
  claims: { scope: 'read' },
});
console.log(key.secret); // ak_live_… (once)

// Later, when a caller presents a key:
const v = await atlas.apiKeys.verify(presentedSecret);
if (v.valid) {
  console.log(v.subject_type, v.subject_id, v.claims);
} else {
  // Every negative — unknown, malformed, revoked, expired — is the SAME
  // { valid: false }, so a caller learns nothing about which keys exist.
}
curl https://api.atlas.dev/v1/api_keys/verify \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"secret":"ak_live_xxx"}'

The verify verdict returns { valid: false } uniformly for every failure mode (unknown, malformed, revoked, expired, or subject-deleted) — the check is safe to expose behind your own API without leaking key existence.

Was this page helpful?