DocsAPIAPI keys

API keys.

How to create, list, and revoke keys programmatically — and through the dashboard. Plus the practices that keep them out of the wrong hands.

§ 01Overview

The endpoints on this page are session-protected — they are how the dashboard manages your keys. The keys themselves are then used to authenticate calls to the data-plane API (/api/v1/...) using Authorization: Bearer esk_.... Two different layers, one identity model.

NoteYou authenticate to these key-management endpoints with the essarion_session cookie, not with an esk_ key. In practice you'll usually create and revoke keys from the dashboard UI; the endpoints exist for power users running their own admin tooling.

§ 02List keys

GET/api/keys

Returns every key on the calling account, ordered by created_at descending. Plaintext is never included — only the prefix.

FieldTypeDescription
idstringStable id for the key. Use this to revoke.
namestringHuman label you set at creation.
prefixstringFirst few characters of the key — esk_live_a1b2 — for display only.
statusstringactive, revoked, or inactive.
created_atstringISO-8601 creation timestamp.
last_used_atstringISO-8601 last successful auth timestamp. Null if never used.
curl
curl https://api.essarion.com/api/keys \
  -H "Cookie: essarion_session=$ESSARION_SESSION"
json — example response
{
  "keys": [
    {
      "id": "key_01HXYZAAA",
      "name": "prod-backend",
      "prefix": "esk_live_a1b2",
      "status": "active",
      "created_at": "2026-04-12T08:00:00Z",
      "last_used_at": "2026-05-01T13:55:21Z"
    },
    {
      "id": "key_01HXYZBBB",
      "name": "local-dev",
      "prefix": "esk_test_c3d4",
      "status": "active",
      "created_at": "2026-03-22T15:14:09Z",
      "last_used_at": null
    }
  ]
}

§ 03Create a key

POST/api/keys

Creates a new key on the calling account. The response includes the plaintext field — once. Subsequent reads will never include it.

Request body

ParamTypeRequiredDescription
namestringyesHuman label. 1-64 characters. Use it to track where the key is deployed.
curl
curl https://api.essarion.com/api/keys \
  -X POST \
  -H "Cookie: essarion_session=$ESSARION_SESSION" \
  -H "Content-Type: application/json" \
  -d '{"name": "prod-backend"}'
json — response (plaintext shown ONCE)
{
  "id": "key_01HXYZAAA",
  "name": "prod-backend",
  "prefix": "esk_live_a1b2",
  "plaintext": "esk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0",
  "status": "active",
  "created_at": "2026-05-01T14:30:00Z",
  "last_used_at": null
}
Cautionplaintext is returned exactly once, in this response. We store only the SHA-256 hash. If you don't capture the plaintext now, the key is unrecoverable — you'll have to revoke it and create a new one.

§ 04Revoke a key

DELETE/api/keys/{id}

Marks the key as revoked. The change is immediate — within a few seconds, calls authenticated with the revoked key will return 401 with code KEY_REVOKED. Revocation is permanent; you cannot reactivate.

curl
curl https://api.essarion.com/api/keys/key_01HXYZAAA \
  -X DELETE \
  -H "Cookie: essarion_session=$ESSARION_SESSION"

§ 05Best practices

The technical surface is small. The practices around it are what keep your account safe.

Rotate periodically

Even without a known compromise, rotate keys on a schedule. Quarterly is a sensible default for production, monthly for high-risk environments. Create the new key, deploy it, verify traffic on the new prefix in the dashboard, then revoke the old.

Scope keys to environments

One key per environment, per service. Don't share local-dev with prod, don't share prod-backend with the cron worker. When something does go wrong, granular keys mean the blast radius of a revocation is one service, not the whole stack.

Store as env vars or in a secrets manager

Read keys from process.env / os.environ at runtime; populate the env from your platform's secrets manager. Never write keys to log lines, error reports, or shell history.

Never commit, never ship to clients

Add .env* to your .gitignore and verify with a pre-commit secret scanner. Never embed keys in a frontend bundle, mobile app, or browser extension — anything that ships to a user can be reverse-engineered. Browser-side workflows must broker through your own backend.

TipThe dashboard surfaces last_used_at on every key. Audit periodically; any key that hasn't been used in 90 days is a candidate for revocation, even if it's not in active rotation.