Skip to navigation

Management API keys

Provision, restrict, budget, and track API keys through the Management API

The Management API issues, rotates, restricts, and caps your organization’s API keys from code, such as one key per customer or employee. It authenticates with a management key that can never make model calls.

Management keys

Create management keys under API keys → Management keys in the dashboard, the only place they’re made. The raw mgmt_ key is shown once, acts on one organization, returns 401 on model endpoints, and should stay server-side. New keys carry all four scopes; older keys need a re-mint to gain newer ones.

ScopeGrants
manage_keysCreate, update, and delete API keys
read_usageRead keys and usage
manage_projectsThe Projects API
manage_routingOrganization routing policies

Send it to https://api-gateway.merge.dev as Authorization: Bearer mgmt_....

Create a key

POST /v1/keys returns 201 with the raw mg_ key, exactly once. All body fields are optional.

FieldMeaning
nameLabel shown in the key list and usage views, such as customer-acme
limit, limit_resetSpend limit in USD (greater than 0) and its window: daily, weekly, or monthly
project_idAttributes every request to that project. Can’t change after creation
allowed_modelsModel allowlist

Creation returns 403 phone_verification_required until your organization verifies a phone number, and 403 payment_method_required when a non-Free organization has no payment method on file.

curl -X POST https://api-gateway.merge.dev/v1/keys \
-H "Authorization: Bearer $MERGE_GATEWAY_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "customer-acme", "limit": 50, "limit_reset": "monthly"}'

The response is a key object plus key. hash is the stable, log-safe ID for every other call.

{
"hash": "a1b2c3d4e5f6",
"name": "customer-acme",
"label": "mg_8Kx2pQr",
"disabled": false,
"limit": 50,
"limit_reset": "monthly",
"usage": 0,
"limit_remaining": 50,
"created_at": "2026-06-02T17:04:00Z",
"project_id": null,
"allowed_models": null,
"routing_policy_id": null,
"key": "mg_8Kx2pQrS..."
}

Manage keys

EndpointDoes
GET /v1/keysLists keys newest first as {object, data, has_more}, at most 100 per page. Page with offset and limit while has_more is true
GET /v1/keys/{hash}Returns one key with its current usage
PATCH /v1/keys/{hash}Updates name, disabled, limit, limit_reset, allowed_models, or routing_policy_id
DELETE /v1/keys/{hash}Revokes the key immediately and returns 204. Its past spend stays in usage reporting

On PATCH, omitted fields are left alone, null clears allowed_models or routing_policy_id, "limit": null leaves the limit in place, and project_id returns 400. Pause a key with "disabled": true. Full schemas: API reference.

Restrict which models a key can call

allowed_models limits a key you hand to a team or customer to listed models.

cURL
curl -X PATCH https://api-gateway.merge.dev/v1/keys/a1b2c3d4e5f6 \
-H "Authorization: Bearer $MERGE_GATEWAY_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"allowed_models": ["openai/gpt-5.4-mini", "anthropic/claude-haiku-*"]}'
RuleDetail
EntriesCanonical provider/model IDs. A bare name such as gpt-5.4-mini returns 400
WildcardsOne trailing * matches a prefix, such as anthropic/claude-opus-*. A leading or interior * returns 400
Aliases@alias/ entries return 400. List the models the policy routes to instead
SizeUp to 200 entries, duplicates collapsed
[]Denies every model
Omitted or nullUnrestricted

Pinning a disallowed model returns 403 model_not_allowed. Under a routing policy, the allowlist filters candidates instead, failing only when none is allowed. It applies on every endpoint, alongside your organization’s blocklist.

Bind a routing policy to a key

routing_policy_id gives one key its own routing without a project or per-request field. Rebinding needs no rotation; null unbinds.

cURL
curl -X PATCH https://api-gateway.merge.dev/v1/keys/a1b2c3d4e5f6 \
-H "Authorization: Bearer $MERGE_GATEWAY_MANAGEMENT_KEY" \
-H "Content-Type: application/json" \
-d '{"routing_policy_id": "3f0a9c1e-5b7d-4a2f-8c61-9d4e2b7a0f13"}'

A policy named on the request beats the binding, which beats customer, project, and organization defaults (precedence). POST /v1/embeddings ignores bindings.

Binding toResult
A policy in another organization404
An inactive policy400
A policy scoped to a different project or customer than the key400. Bind a policy scoped to the key’s project, or an organization policy

Per-key spend limits

A key with limit and limit_reset returns 402 api_key_limit_exceeded once the current window’s spend reaches the limit. Windows reset at midnight UTC (weekly on Monday, monthly on the 1st). Each key object reports the window’s usage and limit_remaining for showing a customer their balance. See how this combines with other scopes in Budgets.

Per-key usage

Usage & spend → By attribution → API key lists each key’s requests, tokens, and spend. Management API keys record no creating user, so give each a descriptive name, such as customer-acme or alice@acme.com.

Next steps