Skip to content

API keys

An API key authenticates the SDK and direct API calls against your account. A single key grants account-wide access — every key can read and write every resource your role allows. Keys are scoped to your account, never to a specific service or environment.

A concrete example

You set up CI/CD for payments. The deploy pipeline needs to call the smplkit API to register the service and apply config updates. You go to API Keys in the console, click Create, name it ci-payments-deploy, and copy the secret. The key starts with sk_api_ — you paste it into your CI secret store as SMPLKIT_API_KEY.

When payments boots in production with that key, the SDK uses it to authenticate every request: registering the service, fetching flags, opening the WebSocket, posting metrics.

What an API key grants

Every API key carries the role of the user who minted it (in practice: the role at mint time — keys outlive role changes). All API operations the role can perform are available to the key.

  • OWNER-minted keys can do anything — including billing, account deletion. Only mint these for trusted automation that genuinely needs them.
  • ADMIN-minted keys can manage users, environments, and resources. Can't touch billing.
  • MEMBER-minted keys can read and write configs, flags, loggers, contexts. Can't manage users or billing.
  • VIEWER-minted keys are read-only.

The key's scope (the operations it can perform) is the role's scope. There's no per-environment or per-product narrowing — a single key works across all environments and all three products in the account.

Key format

Customer keys all start with the prefix sk_api_ followed by a long random secret:

sk_api_lI8aR2vP9qK7nM5xY3bT6sZ1cF4hG0jW8eN2dQ5rA7uV9bC1mX3yT6sZ4hF7

Treat the secret like a password. The console shows it once at creation time — there is no API or UI to retrieve a key after creation. If you lose it, revoke and create a new one.

How keys are minted

Two paths:

  • Console. Go to API Keys, click Create API Key, name it, copy the secret. ADMIN+ only.
  • API. POST /api/v1/api_keys with { name: "...", expires_at: "...", scopes: {...} }. The response includes the secret in plain text exactly once.

API key writes additionally require the requester's email to be verified — unverified users see a 403 even if they're an ADMIN. This blocks abuse via newly-created accounts whose email hasn't been confirmed.

There is no auto-created Default key for new accounts. You must explicitly create your first key after signing up. (This is a divergence from earlier design notes that mentioned a default key — the platform does not currently mint one.)

Who can mint vs revoke

API key writes (create, rename, revoke, delete) are restricted to OWNER and ADMIN. API key reads (list, get) are open to every role.

The reasoning is sharp: an API key grants account-wide write access, and minting one would let a downgraded user retain access after a role demotion. Restricting key creation to OWNER+ADMIN — the same roles that can change other users' roles — keeps the access model coherent.

ActionOWNERADMINMEMBERVIEWER
List, get keys
Create, rename, revoke, delete

Lifecycle and revocation

Three operations affect a key's usability:

  • Revoke (POST /api/v1/api_keys/{id}/actions/revoke). Sets the key to REVOKED status. The secret stops authenticating; the row stays for audit. Revoke when a key may have been exposed.
  • Delete (DELETE /api/v1/api_keys/{id}). Soft-deletes the row entirely. The secret stops authenticating; the row is excluded from listings.
  • Expiration (expires_at at create time). The secret stops authenticating after the configured timestamp. Expired keys are listed but show their status as expired.

Once a key stops working, every SDK using it will fail authentication on the next request. Plan rotation accordingly. See Create and rotate API keys.

Limits

  • 50 API keys per account. Revoked and soft-deleted keys do not count.

What "scopes" do today

The API key resource has a scopes field reserved for future per-resource narrowing. Today, the field is informational — keys always operate at the role's full scope. Treat any value you set as documentation for your own bookkeeping; the platform does not enforce it.