Authorization and
X-Namespace headers, isolation guarantees), see
Security & Tenancy. For rate-limit tiers and usage
pools, see Rate Limits & Quotas.
Managing keys requires an admin key. Every endpoint on this page requires
a key with the
admin permission. Your organization ships
with a protected admin-key you can use to mint your first scoped keys.How a key looks
When you create a key, the plaintext secret is returned exactly once — it is hashed (SHA-256) at rest and can never be read back. Store it immediately in a secrets manager or environment variable.Create a key
POST /v1/organizations/users/{user_email}/api-keys — create a key owned by the
user at {user_email} (use your own email to create keys for yourself).
key:
Request fields
string
required
Human-friendly label (1–100 chars). Used to reference the key in
update/rotate/revoke calls. Must be unique among your active keys.
string[]
default:"[read, write, delete]"
Permission levels granted to the key. Defaults to full
read+write+delete
access — pass a narrower list explicitly when you want a restricted key. See
Permissions.ResourceScope[]
default:"[] (org-wide)"
Resource-level restrictions. Omitting scopes grants org-wide access. See
Restrict a key to specific resources.
integer
Per-key requests-per-minute ceiling. Defaults to your plan limit when absent.
See Per-key rate limits.
string (ISO 8601)
UTC timestamp when the key auto-expires. Omit for a non-expiring key.
string
Optional note (≤500 chars) explaining the key’s purpose.
string
End-user identifier. Setting this makes the key user-scoped for
document-level ACL — see End-user keys.
string[]
CORS allowlist of web origins (exact or wildcard-subdomain). When set, browser
requests must send a matching
Origin header. See Restrict a key to browser
origins.Permissions
Every key carries one or more of four permission levels. They form a strict hierarchy — a higher level implies all lower ones, so you never list more than the strongest you need."permissions": ["read"]:
Restrict a key to specific resources
Permissions control what actions a key can take; scopes control which resources it can take them on. A scope is aResourceScope:
enum
required
What kind of resource the scope governs:
namespace, collection, bucket,
retriever, cluster, taxonomy (and other resource
types).string
required
A literal ID (
ns_production) or a wildcard — * for all, or a prefix
pattern like ns_customer_* to match every namespace for a set of tenants.string[]
A subset of namespace operations the key may
perform within the scope. Omit (or
null) to allow any operation its
permissions already grant.Resource types and operations
resource_type values
resource_type values
organization, user, api_key, namespace, collection, bucket,
retriever, cluster, taxonomy, storage_connection, alert,
annotation, secret, webhook.operations values (within a namespace)
operations values (within a namespace)
Data:
read_data, write_data, delete_data ·
Retrieval: execute_retriever, create_retriever, delete_retriever ·
Jobs: execute_job, cancel_job ·
Clusters: create_cluster, delete_cluster, modify_cluster ·
Infrastructure: modify_infrastructure, manage_permissions.Common bundles: read-only ["read_data", "execute_retriever"];
data-engineer ["read_data", "write_data", "execute_job"].Per-key rate limits
Setrate_limit_override to cap a single key’s requests per minute — useful for
throttling a third-party integration below your plan’s default:
Restrict a key to browser origins
Setallowed_origins to a CORS allowlist of web origins. When set, any
browser request using the key must send an Origin header that matches the
list — an exact origin (https://app.example.com) or a wildcard subdomain
(https://*.example.com) — otherwise the request is rejected with a 403.
Requests that send no Origin header (server-side curl and the SDKs) are
unaffected. This is enforced org-wide, on every route, for any key that carries
an allowlist.
Set it on create, or change it later with PATCH. An empty list clears the
restriction:
Rotate, expire, and revoke
1
Rotate — issue a new secret, invalidate the old one
POST /v1/organizations/users/{user_email}/api-keys/{key_name}/rotate
returns a new plaintext key and immediately revokes the previous
secret. The key_id and settings carry over; only the secret changes.2
Expire — set an automatic cutoff
Set
expires_at on create or via PATCH. Once passed, the key’s status
flips to expired and it stops authenticating. Expired keys cannot be
reactivated — create or rotate instead.3
Revoke — kill a key immediately
DELETE /v1/organizations/users/{user_email}/api-keys/{key_name} sets the
key’s status to revoked. It’s a soft revoke (the record is retained for
the audit trail), and it cannot be undone.status is always one of active, revoked, or expired, and
last_used_at records the timestamp of its most recent successful request — a
quick way to find stale keys worth revoking. List a user’s keys (add
?include_revoked=true to see revoked ones) with:
The organization’s primary
admin-key is protected — it cannot be
updated, rotated, or deleted (the Studio UI depends on it). Create additional
scoped keys for specific use cases, and if the admin-key is ever
compromised, contact support.Audit trail
Every key lifecycle event is written to your organization’s audit log with the acting user and a timestamp. Keys recordcreated_by and revoked_by
(with revoked_at) directly, and the audit log captures the actions
api_key_created, api_key_rotated, api_key_revoked, and
api_key_scope_updated — each with the actor, resource, and what changed.
Monitor usage per key
Attribute traffic and spend to individual keys. Metrics come from the analytics pipeline (ClickHouse) and default to the last 7 days unless you passstart
and end (ISO 8601).
GET /v1/organizations/api-keys/{key_id}/usage/endpoints.
Usage endpoints are keyed by
key_id (e.g. key_a1b2…), not the key’s
name. Grab the key_id from the list response above. Your billing usage
records also carry the attributing key_id, so credit spend reconciles to the
exact key that drove it.Key types
Most keys you create are standard keys, but Mixpeek issues a few specialized types for different jobs:End-user keys for multi-tenant apps
If you’re building an app where your own end-users each see only their data, create a key with aprincipal_id. Mixpeek issues a usr_sk_ user-scoped
key, and every document read made with it is automatically filtered to documents
that principal owns or has been granted access to — enforced server-side, so a
tampered client can’t widen its own view.
principal_id is an identifier for an end-user in your application, not a
Mixpeek organization user. This is the building block for row-level security —
see Document-Level ACL for the full ownership and
grant model, and Permissions for how it composes with
external OpenFGA authorization.Retriever-scoped keys
To embed a single retriever in a browser app or hand it to a customer, mint aret_sk_ key scoped to just that retriever — it can execute the retriever
and nothing else, and its scope/permissions are fixed at creation. Only the
retriever’s owner can create one.
POST /v1/retrievers/{retriever_id}/api-keys:
allowed_origins works exactly as it does on
standard keys — a CORS allowlist enforced
for browser requests, and the same defense-in-depth caveat applies. Because a
ret_sk_ key is designed to be embedded in a browser, always pair it with a
short expires_at and treat the key as public.
Manage keys from Studio
Everything on this page is also available without the API: in Studio, go to Settings → API Keys to create, scope, rotate, revoke, and view per-key usage.Related
Security & Tenancy
The auth model, namespace isolation, and secrets vault.
Rate Limits & Quotas
Plan tiers, usage pools, and how
rate_limit_override fits in.Document-Level ACL
Row-level security driven by user-scoped
principal_id keys.Permissions
Retrieval-time authorization and OpenFGA integration.
API reference — Create key
Full request/response schema for every key endpoint.
API reference — Per-key usage
Usage and endpoint-breakdown response schemas.

