Master Keys
Provision projects and gateway API keys programmatically with org-scoped bearer tokens (Enterprise only)
Master Keys
Master keys are org-scoped bearer tokens that let you create projects and gateway API keys programmatically — without going through the dashboard. They are intended for server-to-server provisioning (e.g. multi-tenant onboarding from your own backend).
Master keys are available on the Enterprise plan only. Contact us at contact@llmgateway.io to enable them for your organization.
Security
- Master keys are stored as HMAC-SHA256 hashes in the database (using the
GATEWAY_API_KEY_HASH_SECRETsecret). The plain token is shown to you only once at creation time. - Each master key is scoped to a single organization and cannot access resources in other organizations.
- Deleting or deactivating a master key revokes all programmatic access immediately.
- All creates/deletes/status changes are recorded in your organization audit log.
Limits
- Maximum 10 active master keys per organization.
- Programmatic project and API-key creation enforces the same per-org and per-project limits as the dashboard flow.
Managing master keys
In the dashboard, go to Organization → Master Keys. From there you can:
- Create a new master key (the plain token is shown once — copy it immediately).
- View the masked token, status, creator, and last-used timestamp for each existing key.
- Activate / deactivate or delete keys.
Authentication
All programmatic endpoints live under /v1/master/* and require a master key in the Authorization header:
Authorization: Bearer llmgmk_...A request with a missing, invalid, inactive, or non-enterprise master key receives a 401 / 403 response.
Endpoints
List projects
GET /v1/master/projects
Returns all non-deleted projects in the master key's organization.
curl https://internal.llmgateway.io/v1/master/projects \
-H "Authorization: Bearer $MASTER_KEY"Response (200):
{
"projects": [
{
"id": "proj_...",
"name": "Customer ACME",
"organizationId": "org_...",
"cachingEnabled": false,
"cacheDurationSeconds": 60,
"mode": "hybrid",
"status": "active",
"createdAt": "...",
"updatedAt": "..."
}
]
}Create a project
POST /v1/master/projects
curl -X POST https://internal.llmgateway.io/v1/master/projects \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer ACME",
"cachingEnabled": false,
"mode": "hybrid"
}'Body parameters:
| Field | Type | Description |
|---|---|---|
name | string | Project name (1–255 chars) |
cachingEnabled | boolean (optional) | Default false |
cacheDurationSeconds | number (optional) | 10–31536000, default 60 |
mode | "api-keys" | "credits" | "hybrid" (optional) | Default "hybrid" |
Response (201): the created project.
Update a project
PATCH /v1/master/projects/{id}
Updates a project owned by the master key's organization. All body fields are optional; provide only the ones you want to change.
curl -X PATCH https://internal.llmgateway.io/v1/master/projects/proj_... \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer ACME (renamed)",
"cachingEnabled": true,
"status": "inactive"
}'Body parameters (all optional, at least one required):
| Field | Type | Description |
|---|---|---|
name | string | 1–255 chars |
cachingEnabled | boolean | |
cacheDurationSeconds | number | 10–31536000 |
mode | "api-keys" | "credits" | "hybrid" | |
status | "active" | "inactive" | Toggle the project without deleting |
Response (200): the updated project.
Delete a project
DELETE /v1/master/projects/{id}
Soft-deletes a project (sets status to "deleted"). Cascades to its API keys.
curl -X DELETE https://internal.llmgateway.io/v1/master/projects/proj_... \
-H "Authorization: Bearer $MASTER_KEY"Response (200):
{ "message": "Project deleted successfully" }Create a gateway API key
POST /v1/master/keys
curl -X POST https://internal.llmgateway.io/v1/master/keys \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "proj_...",
"description": "Customer ACME — production key"
}'Body parameters:
| Field | Type | Description |
|---|---|---|
projectId | string | Must belong to the master key's organization |
description | string | API key description (1–255 chars) |
usageLimit | string (optional) | Lifetime usage limit |
periodUsageLimit | string (optional) | Recurring period usage limit |
periodUsageDurationValue | number (optional) | Required if periodUsageLimit is set |
periodUsageDurationUnit | "hour" | "day" | "week" | "month" (optional) | Required if periodUsageLimit is set |
The created gateway API key's plain token is returned in the response only once. Persist it immediately on your side.
Response (201):
{
"apiKey": {
"id": "ak_...",
"token": "llmgtwy_...",
"description": "Customer ACME — production key",
"status": "active",
"projectId": "proj_...",
"createdBy": "usr_...",
"createdAt": "...",
"updatedAt": "..."
}
}Update a gateway API key
PATCH /v1/master/keys/{id}
Updates an API key in a project owned by the master key's organization. All body fields are optional; provide only the ones you want to change.
curl -X PATCH https://internal.llmgateway.io/v1/master/keys/ak_... \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "inactive",
"usageLimit": "100.00"
}'Body parameters (all optional, at least one required):
| Field | Type | Description |
|---|---|---|
description | string | 1–255 chars |
status | "active" | "inactive" | |
usageLimit | string | null | Lifetime usage limit (null to clear) |
periodUsageLimit | string | null | Recurring period limit (null to clear) |
periodUsageDurationValue | number | null | Required if periodUsageLimit is set |
periodUsageDurationUnit | "hour" | "day" | "week" | "month" | Required if periodUsageLimit is set |
Response (200): the updated API key (the plain token is not included — it is only returned at creation).
Delete a gateway API key
DELETE /v1/master/keys/{id}
Soft-deletes the API key (sets status to "deleted"). Any in-flight requests using the key will be rejected immediately on next auth check.
curl -X DELETE https://internal.llmgateway.io/v1/master/keys/ak_... \
-H "Authorization: Bearer $MASTER_KEY"Response (200):
{ "message": "API key deleted successfully" }The auto-generated playground API key cannot be deleted via the master API.
IAM rules
Each gateway API key can have one or more IAM rules that restrict which models, providers, or pricing tiers it is allowed to use. Rules are evaluated at request time by the gateway. A key with no active rules has no IAM restrictions.
Rule types:
ruleType | Description |
|---|---|
allow_models | Only the listed models are permitted |
deny_models | The listed models are blocked |
allow_providers | Only the listed providers are permitted |
deny_providers | The listed providers are blocked |
allow_pricing | Only models matching the pricing constraint are permitted |
deny_pricing | Models matching the pricing constraint are blocked |
The ruleValue JSON object holds the rule's parameters. The fields it accepts depend on the ruleType:
| Field | Type | Used by |
|---|---|---|
models | string[] | allow_models, deny_models |
providers | string[] | allow_providers, deny_providers |
pricingType | "free" | "paid" | allow_pricing, deny_pricing |
maxInputPrice | number | allow_pricing, deny_pricing |
maxOutputPrice | number | allow_pricing, deny_pricing |
All endpoints scope by the master key's organization: a 404 is returned if the API key (or rule) is not part of the authenticated master key's organization.
List IAM rules
GET /v1/master/keys/{id}/iam
curl https://internal.llmgateway.io/v1/master/keys/ak_.../iam \
-H "Authorization: Bearer $MASTER_KEY"Response (200):
{
"rules": [
{
"id": "iam_...",
"apiKeyId": "ak_...",
"ruleType": "allow_models",
"ruleValue": {
"models": ["openai/gpt-4o", "anthropic/claude-3-5-sonnet"]
},
"status": "active",
"createdAt": "...",
"updatedAt": "..."
}
]
}Create an IAM rule
POST /v1/master/keys/{id}/iam
curl -X POST https://internal.llmgateway.io/v1/master/keys/ak_.../iam \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"ruleType": "allow_models",
"ruleValue": {
"models": ["openai/gpt-4o", "anthropic/claude-3-5-sonnet"]
}
}'Body parameters:
| Field | Type | Description |
|---|---|---|
ruleType | rule type enum (above) | Required |
ruleValue | object (see table above) | Must include the fields appropriate for the chosen type |
status | "active" | "inactive" | Optional, defaults to "active" |
Response (201): the created IAM rule.
Update an IAM rule
PATCH /v1/master/keys/{id}/iam/{ruleId}
All body fields are optional; provide only the ones you want to change.
curl -X PATCH https://internal.llmgateway.io/v1/master/keys/ak_.../iam/iam_... \
-H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "inactive"
}'Body parameters (all optional, at least one required):
| Field | Type | Description |
|---|---|---|
ruleType | rule type enum (above) | Change the rule type |
ruleValue | object (see table above) | Replace the rule value |
status | "active" | "inactive" | Activate or deactivate without deleting |
Response (200): the updated IAM rule.
Delete an IAM rule
DELETE /v1/master/keys/{id}/iam/{ruleId}
Permanently removes an IAM rule from the API key.
curl -X DELETE https://internal.llmgateway.io/v1/master/keys/ak_.../iam/iam_... \
-H "Authorization: Bearer $MASTER_KEY"Response (200):
{ "message": "IAM rule deleted successfully" }How is this guide?
Last updated on