API Keys
OverviewLink to section
API keys authenticate your requests to the Mixedbread API. Every key belongs to an organization and inherits its Stores, billing, and limits. Pass a key as a bearer token:
curl https://api.mixedbread.com/v1/stores \
-H "Authorization: Bearer $MXBAI_API_KEY"Create and manage keys on the API Keys page of your dashboard.
Access modesLink to section
When you create a key you choose how much of the API it can reach:
- Full access — the key can use every endpoint available to the organization. This is the default.
- Custom — the key carries a list of scopes, and every request is checked against them. Anything you do not grant is refused.
A custom key is the right choice whenever a key leaves your own backend: a search-only key for a client-side app, a write-only key for an ingestion pipeline, or a key that may answer questions but never delete a Store.
Available scopesLink to section
| Scope | Grants | Applies to |
|---|---|---|
| List stores | View the Stores in the organization | Organization-wide |
| Create store | Create new Stores | Organization-wide |
| Read store | View files and chunks in a Store | Selected Stores or all |
| Write store | Upload and modify files in a Store | Selected Stores or all |
| Delete store | Delete Stores | Selected Stores or all |
| Search store | Read a Store's indexed content: search, agentic search, grep, list chunks, question answering, metadata facets, and query enhancement | Selected Stores or all |
| Completions | Use the Chat Completions and Responses APIs | Organization-wide |
Scoping to specific StoresLink to section
Read store, Write store, Delete store, and Search store can be granted either across every Store in the organization or against an explicit list of Stores. A key restricted to a list may only touch those Stores — a request naming any other Store is refused, and so is a request that names no Store at all, since there is nothing to match the grant against.
Grant a scope organization-wide when the key should keep working for Stores you create later; grant it per Store when the key belongs to one workload.
The completions scopeLink to section
The Completions scope gates the agent-facing endpoints, separately from anything a key may do with Stores:
| Method | Endpoints |
|---|---|
create | POST /v1/chat/completions, POST /v1/chat/completions/{id}/transcript/close, POST /v1/responses |
read | GET /v1/chat/completions, GET /v1/chat/completions/{id}, GET /v1/chat/completions/{id}/turns, GET /v1/chat/completions/{id}/messages, GET /v1/responses/{id}, GET /v1/responses/{id}/input_items |
delete | DELETE /v1/chat/completions/{id}, DELETE /v1/responses/{id} |
The dashboard exposes this as a single Completions checkbox, which grants all three methods together.
The Completions scope is independent of the Store scopes. A key that may run completions still needs Search store on a Store before the hosted search tools can retrieve from it, and a key with only Completions can generate but never search.
Keys created before the Completions scope existed keep working unchanged: scope-restricted keys were granted all three completions methods, and full-access keys were never restricted in the first place.
Scopes over the APILink to section
The /v1/api-keys endpoint takes the same scopes as a list of entries. Each
entry has a method, a resource_type of store or completions, and a
resource_id that names one Store or is null for organization-wide:
{
"name": "Search and answer",
"scope": [
{ "method": "search", "resource_type": "store", "resource_id": "8f2b…" },
{ "method": "create", "resource_type": "completions", "resource_id": null },
{ "method": "read", "resource_type": "completions", "resource_id": null }
]
}Omit scope entirely to create a full-access key.
null and an empty list both create a full-access key — an empty array is
stored as "no restrictions", not as "no permissions". To lock a key down, send
the scopes you want to grant; there is no way to express a key that may do
nothing.
When a scope is missingLink to section
A request the key's scopes do not cover fails with 403 and the error code
permission_denied_error, naming the scope that was missing:
{
"type": "permission_denied_error",
"code": "permission_denied_error",
"message": "This API key is missing the create scope for completions."
}Scopes are fixed when the key is created. To change what a key may do, create a replacement with the scopes you want and revoke the old one.