LLM Gateway
Features

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_SECRET secret). 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:

FieldTypeDescription
namestringProject name (1–255 chars)
cachingEnabledboolean (optional)Default false
cacheDurationSecondsnumber (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):

FieldTypeDescription
namestring1–255 chars
cachingEnabledboolean
cacheDurationSecondsnumber10–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:

FieldTypeDescription
projectIdstringMust belong to the master key's organization
descriptionstringAPI key description (1–255 chars)
usageLimitstring (optional)Lifetime usage limit
periodUsageLimitstring (optional)Recurring period usage limit
periodUsageDurationValuenumber (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):

FieldTypeDescription
descriptionstring1–255 chars
status"active" | "inactive"
usageLimitstring | nullLifetime usage limit (null to clear)
periodUsageLimitstring | nullRecurring period limit (null to clear)
periodUsageDurationValuenumber | nullRequired 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:

ruleTypeDescription
allow_modelsOnly the listed models are permitted
deny_modelsThe listed models are blocked
allow_providersOnly the listed providers are permitted
deny_providersThe listed providers are blocked
allow_pricingOnly models matching the pricing constraint are permitted
deny_pricingModels matching the pricing constraint are blocked

The ruleValue JSON object holds the rule's parameters. The fields it accepts depend on the ruleType:

FieldTypeUsed by
modelsstring[]allow_models, deny_models
providersstring[]allow_providers, deny_providers
pricingType"free" | "paid"allow_pricing, deny_pricing
maxInputPricenumberallow_pricing, deny_pricing
maxOutputPricenumberallow_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:

FieldTypeDescription
ruleTyperule type enum (above)Required
ruleValueobject (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):

FieldTypeDescription
ruleTyperule type enum (above)Change the rule type
ruleValueobject (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

On this page

Ready for production?

Ship to production with SSO, audit logs, spend controls, and guardrails your security team will approve.

Explore Enterprise