Management API
Configure your gateway.
Keep every change intentional.
Manage apps, shared providers, access keys and configuration from one tenant-scoped API. Start with a workflow, then explore every request field.
Use a dedicated management key to configure the LLM Gateway from deployment pipelines, internal tools and administration scripts. Each key belongs to one tenant, carries explicit permissions, and works only when both deployment enablement and tenant opt-in are active.
Use the Management API to configure LLM Gateway apps, shared providers, credentials, prompts and stored configuration. Explore complete input specifications and examples, or download the OpenAPI reference.
Enable in the console
- Go to Settings > AI Gateway > LLM Gateway and open the Management API tab.
- Turn on Allow management keys for this organization. Turning it off later suspends every management key until you turn it back on.
- Under Issue a management key, enter a Key name, an optional Expiry, and the Scopes it needs.
- Click Issue key and store the value. It is shown only once.
A key acts for the whole organization within its scopes and cannot be limited to one app. Revoke a key from the keys table on the same tab. See Authentication and management keys for details.
Choose a resource
Create, read, configure and pause applications.
Explore referenceProviders & catalogsConfigure shared credentials, test models, and read catalogs and config history.
Explore referenceAuthenticationEnable access and issue scoped management keys.
Explore referenceGateway credentialsIssue, reveal, expire and revoke app keys.
Explore referenceQuilrQL behaviorUnderstand app defaults and policy-governed settings.
Explore referencePromptsManage Prompt Store content.
Explore referenceThe management model
Availability
Not Generally Available means the feature is not currently supported by management v1. The label does not promise preview access or a release date. The endpoint reference and OpenAPI paths contain only implemented operations.
Defaults
- Management keys have no expiry by default. An administrator can supply one.
- Creating an app issues one gateway key, named Default unless specified.
- Disabling tenant management suspends its keys. Unexpired, unrevoked keys work again when the tenant is re-enabled.
- Disabling an app preserves its keys, settings and history. Disabling a shared provider preserves its attachments.
- Provider saves validate locally. Supported model tests are separate explicit requests; connection tests currently return unsupported.
- Configuration writes go to the central management service. Customer gateway nodes receive synchronized changes.
When QuilrQL is enabled, updates to governed app settings still save. The response identifies the fields that remain inactive until QuilrQL authority is disabled. Creating an eligible app under existing authority can publish an app-specific allowed-models default. See QuilrQL behavior.
Find an endpoint
Search by resource, path, action or HTTP method. Open an endpoint to see its scopes, parameters, complete body schema and examples.
60 of 60 operations
/capabilitiesRead capabilities/openapi.jsonGet openapi/appsList apps/appsCreate an app/apps/{app_name}Read an app/apps/{app_name}Update or disable an app/providersList shared providers/providersCreate a shared provider/providers/{label}Read a shared provider/providers/{label}Update or disable a provider/providers/{label}/testTest connection or model/apps/{app_name}/providersList app providers/apps/{app_name}/providers/{label}Attach a shared provider/apps/{app_name}/providers/{label}Detach an app provider/apps/{app_name}/provider-conversionConvert inline providers/apps/{app_name}/keysList gateway credentials/apps/{app_name}/keysIssue a gateway credential/apps/{app_name}/keys/{key_id}Get key/apps/{app_name}/keys/{key_id}Change gateway key expiry/apps/{app_name}/keys/{key_id}Revoke a gateway credential/apps/{app_name}/keys/{key_id}/revealReveal a gateway credential/apps/{app_name}/promptsList prompts/apps/{app_name}/prompts/{prompt_id}Read a prompt/apps/{app_name}/prompts/{prompt_id}Create or replace a prompt/apps/{app_name}/prompts/{prompt_id}Delete a prompt/apps/{app_name}/versionsList app configuration versions/apps/{app_name}/versions/{version_id}Read a configuration version/apps/{app_name}/versions/{version_id}/rollbackRoll back app configuration/smart-groupsList smart groups/smart-groups/{group_name}Read a smart group/custom-definitionsList custom definitions/custom-definitions/{definition_id}Read a custom definition/auditGet audit/operations/{operation_id}Get operation/operations/{operation_id}/recoverPost recover/appRead an app (query locator)/appUpdate or disable an app (query locator)/app/providersList app providers (query locator)/app/providers/{label}Attach a shared provider (query locator)/app/providers/{label}Detach an app provider (query locator)/app/provider-conversionConvert inline providers (query locator)/app/keysList gateway credentials (query locator)/app/keysIssue a gateway credential (query locator)/app/keys/{key_id}Get key (query locator)/app/keys/{key_id}Change gateway key expiry (query locator)/app/keys/{key_id}Revoke a gateway credential (query locator)/app/keys/{key_id}/revealReveal a gateway credential (query locator)/app/promptsList prompts (query locator)/app/prompts/{prompt_id}Read a prompt (query locator)/app/prompts/{prompt_id}Create or replace a prompt (query locator)/app/prompts/{prompt_id}Delete a prompt (query locator)/app/versionsList app configuration versions (query locator)/app/versions/{version_id}Read a configuration version (query locator)/app/versions/{version_id}/rollbackRoll back app configuration (query locator)/admin/tenants/{tenant_id}/settingsRead tenant management settings/admin/tenants/{tenant_id}/settingsEnable or suspend tenant management/admin/tenants/{tenant_id}/keysList management keys/admin/tenants/{tenant_id}/keysIssue a management key/admin/tenants/{tenant_id}/keys/{key_id}Update a management key/admin/tenants/{tenant_id}/keys/{key_id}Revoke a management keyContinue
Start with the end-to-end example, inspect the full app configuration schema, or review errors, concurrency and retry semantics. Download the OpenAPI 3.1 reference for all operations and input schemas.
Quick start
This workflow checks access, creates a shared provider, creates an app, reads it, then disables it without losing configuration.
1. Prepare access
Management requests go to the management origin: the central QuilrAI service for your organization, not the regional inference URLs such as guardrails-usa-2.quilr.ai. Regional gateway nodes reject management requests with 503 central_service_required.
In the console, turn on Allow management keys for this organization and issue a key (see Enable in the console). For this workflow, the key needs read, providers:write, config:write and credentials:write.
export MANAGEMENT_ORIGIN='<management-origin>' # from the table above, e.g. https://...
export MANAGEMENT_KEY='<management-key>'
export PROVIDER_API_KEY='<provider-api-key>'
Keep secrets in your automation secret store. These example values are placeholders, not live credentials.
Check the origin and key with a read-only call. It changes nothing and needs only the read scope:
curl --fail-with-body \
"$MANAGEMENT_ORIGIN/llmgateway/management/v1/capabilities" \
--header "Authorization: Bearer $MANAGEMENT_KEY"
A 200 response lists scopes, provider_types, app_fields and writes_available. If it fails:
2. Create a shared provider
curl --request POST \
"$MANAGEMENT_ORIGIN/llmgateway/management/v1/providers" \
--header "Authorization: Bearer $MANAGEMENT_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: support-provider-001' \
--data "{\"label\":\"Production OpenAI\",\"provider_name\":\"openai\",\"provider_settings\":{\"api_key\":\"$PROVIDER_API_KEY\"},\"selected_models\":[\"gpt-4.1-mini\"]}"
A 201 response returns provider metadata with credential_configured and an opaque version. Saving does not contact the provider. Use explicit testing when you want to verify connectivity or model access.
3. Create an app
curl --request POST \
"$MANAGEMENT_ORIGIN/llmgateway/management/v1/apps" \
--header "Authorization: Bearer $MANAGEMENT_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: support-app-001' \
--data '{
"name": "Support Bot",
"provider_labels": ["Production OpenAI"],
"tags": ["production", "support"]
}'
Abbreviated creation response; additional stored-setting sections and metadata may be present:
{
"app": {
"name": "Support Bot",
"mode": "gateway",
"enabled": true,
"version": "app-v1",
"provider_labels": ["Production OpenAI"],
"tags": ["production", "support"],
"policy_authority": {"enabled": false, "active_revision": null, "active_checksum": null}
},
"key": {
"key_id": "key_example",
"name": "Default",
"secret": "<new-gateway-key>",
"status": "active",
"expires_at": null
},
"warnings": [],
"operation_id": "operation_example",
"request_id": "req_example"
}
The initial key is issued even when initial_key is omitted. Use the gateway credential for runtime calls. Keep using the management credential for configuration.
When tenant-wide QuilrQL authority is already enabled, app creation captures the app baseline and can publish an app-specific allowed-models default for all app users. Finite configured model lists receive this default; unrestricted providers and SDK/Copilot Studio apps do not get a finite model list. Matching tenant policies, including explicit model denials, still apply. Creation does not enable authority or change existing drafts. See QuilrQL behavior.
4. Read the current version
curl --include \
"$MANAGEMENT_ORIGIN/llmgateway/management/v1/apps/Support%20Bot" \
--header "Authorization: Bearer $MANAGEMENT_KEY"
Use the returned ETag in updates. The example below assumes it is "app-v1"; use the actual value from your read.
5. Disable and re-enable
curl --request PATCH \
"$MANAGEMENT_ORIGIN/llmgateway/management/v1/apps/Support%20Bot" \
--header "Authorization: Bearer $MANAGEMENT_KEY" \
--header 'Content-Type: application/json' \
--header 'If-Match: "app-v1"' \
--data '{"enabled":false}'
This preserves the app, prompts, provider references and keys. After a gateway observes the change, newly admitted traffic is rejected for all app authentication modes. Existing requests finish normally.
To re-enable, read the latest ETag and PATCH {"enabled":true}. Keys that expired or were revoked while the app was disabled remain invalid. Propagation is asynchronous; the API does not promise an instantaneous global kill switch.
Next steps
Authentication and management keys
Two gates enable access: the deployment switch and tenant opt-in. Every management key belongs to exactly one tenant; one tenant can have multiple keys for independent automation clients.
Request authentication
Authorization: Bearer <management-key>
The key establishes the tenant. Caller-supplied tenant headers cannot expand that scope. Gateway inference keys, log-export credentials and management keys are not interchangeable.
Enablement and lifecycle
- Self-hosted only: management is on by default on the central service. Setting
LLMGATEWAY_MANAGEMENT_API_ENABLED=falseturns it off. - An authorized administrator enables management for the tenant.
- The administrator creates a named key with explicit scopes and, optionally, an expiry.
- Store the returned secret. Issue a replacement key before revoking a key used by an existing integration.
Disabling tenant management suspends its keys. Re-enabling restores keys that remain unexpired and unrevoked. This does not enable/disable gateway apps. Tenant admins may continue to inspect enablement and revoke keys while tenant management is suspended, provided the deployment gate is enabled.
Management keys do not expire by default. expires_at is a future RFC 3339 timestamp or null. On PATCH, omission preserves the current expiry and null clears it. Expired and revoked keys are terminal: issue a new key instead of resurrecting one.
Scopes
All scopes listed for an operation are required. No scope implies another.
App creation requires both config:write and credentials:write because it issues an initial gateway credential. Attaching an existing provider needs config:write; changing that shared provider needs providers:write.
Policy scopes (policy:write, policy:publish) and app-restricted management keys are Not Generally Available. The five scopes above are the accepted scopes and apply tenant-wide.
Administration boundary
The /llmgateway/management-admin/v1 routes require Authorization: Bearer <Quilr tenant-admin JWT>. The verified JWT must include the selected tenant in tenantIds, an Admin or Super Admin role, and an identifying sub, userId or email. Tenant headers alone do not authorize access. A management key cannot grant itself permissions or enable its tenant.
GET/PATCH tenant settings controls { "enabled": true }. GET/POST tenant keys lists metadata or creates a management key. PATCH/DELETE a key changes its name/scopes/expiry or revokes it. Dedicated rotation and per-key pause/resume are Not Generally Available; issue a replacement and then revoke the old key.
Lists return each key's version, status, creator, creation/expiry/revocation times and last_used_at. Use the quoted version as If-Match for editing or revoking that key. Management-key timestamps are Unix seconds, potentially fractional; request expires_at values use RFC 3339. List responses never include the secret. Later management-secret retrieval is Not Generally Available; retain the issuance response.
Key creation requires Idempotency-Key. The same administrator can replay the completed issuance response, including its secret, for 24 hours using the same key and payload. After that window, the token cannot create another key. See retry and recovery.
/admin/tenants/{tenant_id}/settingsRead tenant management settings
Tenant-admin JWT. PATCH requires the settings ETag. Suspending management preserves keys; unexpired/unrevoked keys resume on re-enablement.
Verified tenant administratorPath, query & header parameters 1
tenant_id (path)stringrequiredNo request body.
curl --request GET \
'https://management.example.com/llmgateway/management-admin/v1/tenants/tenant_example/settings' \
--header 'Authorization: Bearer <verified-admin-token>'
/admin/tenants/{tenant_id}/settingsEnable or suspend tenant management
Tenant-admin JWT. PATCH requires the settings ETag. Suspending management preserves keys; unexpired/unrevoked keys resume on re-enablement.
Verified tenant administratorPath, query & header parameters 2
tenant_id (path)stringrequiredIf-Match (header)stringrequiredQuoted ETag returned by the latest resource read. Prompt/attachment/rollback writes use the app ETag.
Full request body specification application/json
enabledbooleanrequiredUnknown fields are rejected in this object.
curl --request PATCH \
'https://management.example.com/llmgateway/management-admin/v1/tenants/tenant_example/settings' \
--header 'Authorization: Bearer <verified-admin-token>' \
--header 'If-Match: "resource-version-from-read"' \
--header 'Content-Type: application/json' \
--data '{
"enabled": true
}'
/admin/tenants/{tenant_id}/keysList management keys
Tenant-admin JWT. Creation requires tenant opt-in and returns the secret; lists return metadata including version. Issuance replay is available for 24 hours to the same admin and idempotency key.
Verified tenant administratorPath, query & header parameters 3
tenant_id (path)stringrequiredlimit (query)integeroptionalcursor (query)stringoptionalNo request body.
curl --request GET \
'https://management.example.com/llmgateway/management-admin/v1/tenants/tenant_example/keys?limit=50' \
--header 'Authorization: Bearer <verified-admin-token>'
/admin/tenants/{tenant_id}/keysIssue a management key
Tenant-admin JWT. Creation requires tenant opt-in and returns the secret; lists return metadata including version. Issuance replay is available for 24 hours to the same admin and idempotency key.
Verified tenant administratorPath, query & header parameters 2
tenant_id (path)stringrequiredIdempotency-Key (header)stringrequiredFull request body specification application/json
namestringrequiredexpires_atstring | nulloptionalscopesarray<string>requiredArray item specification
stringValues: "config:write""credentials:read""credentials:write""providers:write""read"
Unknown fields are rejected in this object.
curl --request POST \
'https://management.example.com/llmgateway/management-admin/v1/tenants/tenant_example/keys' \
--header 'Authorization: Bearer <verified-admin-token>' \
--header 'Idempotency-Key: unique-operation-001' \
--header 'Content-Type: application/json' \
--data '{
"name": "Deployment automation",
"scopes": [
"read",
"config:write",
"providers:write",
"credentials:write"
],
"expires_at": null
}'
/admin/tenants/{tenant_id}/keys/{key_id}Update a management key
Use key.version from the list as a quoted If-Match. PATCH changes name/scopes/expiry. DELETE revokes and returns key metadata. Expired/revoked keys cannot be edited.
Verified tenant administratorPath, query & header parameters 3
tenant_id (path)stringrequiredkey_id (path)stringrequiredIf-Match (header)stringrequiredQuoted ETag returned by the latest resource read. Prompt/attachment/rollback writes use the app ETag.
Full request body specification application/json
namestringoptionalexpires_atstring | nulloptionalscopesarray<string>optionalArray item specification
stringValues: "config:write""credentials:read""credentials:write""providers:write""read"
Unknown fields are rejected in this object.
curl --request PATCH \
'https://management.example.com/llmgateway/management-admin/v1/tenants/tenant_example/keys/key_example' \
--header 'Authorization: Bearer <verified-admin-token>' \
--header 'If-Match: "resource-version-from-read"' \
--header 'Content-Type: application/json' \
--data '{
"name": "Production automation",
"scopes": [
"read",
"config:write"
]
}'
/admin/tenants/{tenant_id}/keys/{key_id}Revoke a management key
Use key.version from the list as a quoted If-Match. PATCH changes name/scopes/expiry. DELETE revokes and returns key metadata. Expired/revoked keys cannot be edited.
Verified tenant administratorPath, query & header parameters 3
tenant_id (path)stringrequiredkey_id (path)stringrequiredIf-Match (header)stringrequiredQuoted ETag returned by the latest resource read. Prompt/attachment/rollback writes use the app ETag.
Full request body specification application/json
Unknown fields are rejected in this object.
curl --request DELETE \
'https://management.example.com/llmgateway/management-admin/v1/tenants/tenant_example/keys/key_example' \
--header 'Authorization: Bearer <verified-admin-token>' \
--header 'If-Match: "resource-version-from-read"' \
--header 'Content-Type: application/json' \
--data '{}'
API conventions and errors
Enablement and authentication
Management v1 runs on the central service. Self-hosted operators can turn it off with LLMGATEWAY_MANAGEMENT_API_ENABLED=false (it defaults on); both route families then return 404. Deployments using CLICKHOUSE_MASTER_URL reject management with 503 central_service_required.
Resource routes use /llmgateway/management/v1 and Authorization: Bearer <qlmgmt_...>. The key establishes the tenant. Administrator routes use /llmgateway/management-admin/v1 and a verified tenant-admin JWT; see authentication.
Send JSON bodies with Content-Type: application/json. Requests are capped at 1 MiB, with a 10-second body-read timeout and 32 admitted management requests per HTTP worker. Model probes have a 20-second timeout. Secret-bearing values are omitted from ordinary reads. Responses use Cache-Control: no-store and X-Request-ID.
Names and pagination
Use URL-encoded paths for simple names. For app names containing /, % or other proxy-sensitive characters, use the /app query aliases and encode app_name once. Every app subresource supports the same alias.
Paginated lists accept limit (1-200, default 50) and cursor:
{"items": [], "next_cursor": null, "request_id": "req_example"}
There is no has_more; continue while next_cursor is non-null. A changed collection returns 409 collection_changed; restart pagination. App lists additionally support name substring, tag and enabled=true|false. Provider/group/definition/audit lists support no additional filters. App-provider attachments return an ordered provider_labels array and app version, not a paginated collection.
Versions and preconditions
Read the current resource version, then send its quoted value in If-Match. Missing preconditions return 428; stale versions return 412. Re-read and reconcile the intended change.
App updates, provider attachments/conversion, all prompt mutations and configuration rollback use the app ETag. Provider changes use the provider ETag. Gateway credential changes use the individual credential GET version. Management-key changes use key.version from the admin list. Tenant enablement changes use the settings version.
Prompt creation also requires the app ETag; If-None-Match has no create-only semantics. Lists do not return a collection ETag for editing their members.
Idempotency and recovery
App/provider/gateway-key/management-key creation and app rollback require a distinct Idempotency-Key per intended operation. Reusing it with different input returns 409. Completed responses are encrypted and replayable for 24 hours to the same principal. Expiry does not permit duplicate issuance using that token.
A timeout or 503 does not prove that nothing changed. 503 operation_pending includes error.operation_id when a configuration/creation operation remains incomplete. Configuration recovery uses /operations/{operation_id} and /operations/{operation_id}/recover with the initiating key. Creation recovery retries the original POST and token. See operation recovery.
Provider/credential PATCH and revocation, and provider conversion, have no idempotent replay contract. After a transport/storage error, read current state/version before deciding whether another mutation is needed.
Dates and response formats
Request expires_at values are future RFC 3339 timestamps with a timezone, or null. Gateway credential expiry responses also use RFC 3339. Management-key metadata, management audit, operation creation and provider-test completion times use Unix seconds, potentially fractional. Treat opaque IDs, versions and fingerprints as strings.
Capabilities fields are at the response root, including schema_version, scopes, app_fields, writes_available, policy_updates, policy_authority and model-test support. There is no wrapping capabilities object. Configuration history detail uses version_record. All ordinary JSON responses include request_id; /openapi.json returns an OpenAPI document directly.
Errors
{
"error": {
"code": "operation_pending",
"message": "Creation is incomplete; retry the same Idempotency-Key to recover",
"operation_id": "operation_example"
},
"request_id": "req_example"
}
Deletes return JSON with 200, not 204. Provider tests return 200 with an explicit passed, failed or unsupported outcome; inspect test.code and test.configuration_version. Connection tests currently return unsupported_test_kind.
Propagation and deployment
Central writes synchronize asynchronously to gateway nodes. Whole-app disable rejects new admissions after each node observes the change; existing requests and streams finish. Management-key revocation and tenant suspension are checked against central authority on each admitted management request.
Central HTTP workers and the tenant watcher share persistent DLP_SERVER_DATA_DIR. Management authority, keys, audit and encrypted replay data are central-only; back up DATABASES/llmgateway_management.db and llmgateway_management.replay.key together. Independent replicas with independent data directories are unsupported.
Capability and schema reference
Features marked Not Generally Available in the availability table are not currently supported. The static downloadable reference adds examples to the current implemented routes. The authenticated /openapi.json endpoint returns the backend-generated contract. Use /capabilities for deployed fields/provider types and test support.
/capabilitiesRead capabilities
Deployment support, exact app fields and supported provider/model tests. Fields are returned at the response root.
readNo request body.
curl --request GET \
'https://management.example.com/llmgateway/management/v1/capabilities' \
--header 'Authorization: Bearer <management-key>'
/openapi.jsonGet openapi
Backend-generated OpenAPI document. This endpoint requires read; the downloaded documentation reference adds descriptions and examples.
readNo request body.
curl --request GET \
'https://management.example.com/llmgateway/management/v1/openapi.json' \
--header 'Authorization: Bearer <management-key>'