Skip to main content
An API key authenticates every request to Mixpeek. Keys belong to your organization and are created per user. This page covers creating keys, restricting what they can do (permissions and scopes), rotating and revoking them, monitoring per-key usage, and the special key types that power end-user multi-tenancy. For the broader authentication and tenancy model (the 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.
FieldExampleWhat it is
keymxp_sk_9f3a… (60 chars)The plaintext secret. Shown once, on create/rotate. Send it as Authorization: Bearer <key>.
key_prefixmxp_sk_9f3...First 10 characters + .... A safe display hint so you can tell keys apart in a list — never the full secret.
key_idkey_a1b2c3d4e5f6g7hStable public identifier. Used for usage lookups.
namebackend-serviceHuman label you choose. Used to reference the key in update/rotate/revoke calls.
The plaintext key is never retrievable after creation. If you lose it or suspect exposure, rotate the key — don’t try to recover it.

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).
The response is the key’s metadata plus the one-time plaintext key:

Request fields

name
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.
permissions
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.
scopes
ResourceScope[]
default:"[] (org-wide)"
Resource-level restrictions. Omitting scopes grants org-wide access. See Restrict a key to specific resources.
rate_limit_override
integer
Per-key requests-per-minute ceiling. Defaults to your plan limit when absent. See Per-key rate limits.
expires_at
string (ISO 8601)
UTC timestamp when the key auto-expires. Omit for a non-expiring key.
description
string
Optional note (≤500 chars) explaining the key’s purpose.
principal_id
string
End-user identifier. Setting this makes the key user-scoped for document-level ACL — see End-user keys.
allowed_origins
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.
PermissionImpliesUse it for
readDashboards, analytics, read-only search clients
writereadIngestion and service accounts that create documents
deletewrite, readFull data management (create + remove)
admindelete, write, readOrg administration — managing keys and users requires admin
A route declares the minimum permission it needs, and a key satisfies it if the key’s permission is at least that level. To issue a read-only key for an internal dashboard, create it with "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 a ResourceScope:
resource_type
enum
required
What kind of resource the scope governs: namespace, collection, bucket, retriever, cluster, taxonomy (and other resource types).
resource_id
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.
operations
string[]
A subset of namespace operations the key may perform within the scope. Omit (or null) to allow any operation its permissions already grant.
Example — a key that can only read and search within one customer’s namespace, and nothing else:
An empty scopes list means org-wide access — this is the legacy default, so a key created without scopes can reach every namespace and resource in your organization. To confine a key, you must provide at least one scope. Setting scopes to [] on an update widens the key back to org-wide.

Resource types and operations

organization, user, api_key, namespace, collection, bucket, retriever, cluster, taxonomy, storage_connection, alert, annotation, secret, webhook.
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

Set rate_limit_override to cap a single key’s requests per minute — useful for throttling a third-party integration below your plan’s default:
The override interacts with your organization’s plan tiers and usage pools, which are documented in Rate Limits & Quotas.

Restrict a key to browser origins

Set allowed_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:
The allowlist carries across rotation — a rotated key keeps its origins.
allowed_origins is defense-in-depth, not a standalone security boundary. It only constrains requests that send an Origin header (i.e. browsers); a stolen key used from a non-browser client can omit Origin and bypass it. Pair it with least-privilege permissions and scopes, and treat any key shipped to a browser as public.

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.
A key’s 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 record created_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 pass start and end (ISO 8601).
For a per-endpoint breakdown, call 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:
TypePrefixPurpose
Standardmxp_sk_Regular organization key. Everything above.
User-scopedusr_sk_Carries a principal_id for document-level ACL.
Retriever-scopedret_sk_Locked to executing one published retriever.
Marketplacesk_marketplace_Grants access to a subscribed marketplace retriever.
SessionShort-lived key Studio mints on login to back the UI. Hidden from key lists; not something you manage.

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 a principal_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 a ret_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.

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.