Update AI Gateway Settings
Endpoint
PUT /apiops/settings/ai-gateway
Authentication
Requires a Personal API Access Token with admin privileges.
Header
Authorization: Bearer YOUR_TOKEN
Request
Headers
| Header | Value | Required |
|---|---|---|
| Authorization | Bearer {token} | Yes |
| Content-Type | application/json | Yes |
Path Parameters
None.
Query Parameters
None.
Request Body
This is a partial update: only the top-level fields you send (non-null) are applied — every omitted field preserves its currently stored value.
Full JSON Body Example
{
"defaultConnectTimeoutSeconds": 15,
"defaultStreamTimeoutSeconds": 300,
"defaultRetryCount": 2,
"maxAiRequestBodyBytes": 20971520,
"maxAiBinaryRequestBodyBytes": 52428800,
"maxAiBinaryResponseBodyBytes": 52428800,
"maxToolTurns": 8,
"defaultBudget": {
"enabled": true,
"monthlyBudgetUsd": 500.00,
"hardCapPercent": 100,
"overflowAction": "BLOCK"
}
}
Request Body Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| defaultConnectTimeoutSeconds | integer | No | 10 | Connect timeout to the LLM provider, in seconds. Must be between 1 and 300. |
| defaultStreamTimeoutSeconds | integer | No | 120 | Overall SSE stream timeout, in seconds. Must be between 1 and 3600. |
| defaultRetryCount | integer | No | 0 | Retry attempts on provider error. Must be between 0 and 10. |
| maxAiRequestBodyBytes | integer | No | 10485760 | Max JSON AI request body size in bytes. Must be between 1 and 1073741824 (1 GB). |
| maxAiBinaryRequestBodyBytes | integer | No | 26214400 | Max binary/multipart AI request body size in bytes. Must be between 1 and 1073741824 (1 GB). |
| maxAiBinaryResponseBodyBytes | integer | No | 26214400 | Max binary AI response body size in bytes. Must be between 1 and 1073741824 (1 GB). |
| maxToolTurns | integer | No | 5 | Ceiling on chained agentic tool-call turns. Must not exceed 100; a value <= 0 disables the loop (passthrough). |
| defaultBudget | object | No | budget disabled | Platform-wide default token/cost budget object (see field table below). Sent whole — its nested lists follow null-keeps / empty-wipes semantics. |
defaultBudget Object Fields
| Field | Type | Description |
|---|---|---|
| enabled | boolean | Whether the default budget is enforced |
| tokensPerHour | integer | Hourly token cap; if set, must be >= 1 (null = no limit) |
| tokensPerMinute | integer | Per-minute token cap; if set, must be >= 1 (null = no limit) |
| tokensPerDay | integer | Daily token cap; if set, must be >= 1 (null = no limit) |
| tokensPerMonth | integer | Monthly token cap; if set, must be >= 1 (null = no limit) |
| monthlyBudgetUsd | number | Monthly USD cost cap; if set, must be > 0 (null = no limit) |
| usdPerHour | number | Hourly USD cost cap; if set, must be > 0 (null = no limit) |
| usdPerDay | number | Daily USD cost cap; if set, must be > 0 (null = no limit) |
| softCapPercents | array[integer] | Soft-cap warning thresholds, each in [0, 100] |
| hardCapPercent | integer | Hard-cap threshold in [1, 100] |
| overflowAction | string | Action on overflow: BLOCK, FAILOVER, ALERT_ONLY, CHEAPER_MODEL |
| cheaperModelId | string | Fallback model id used when overflowAction = CHEAPER_MODEL |
| modelBudgets | array | Per-model budget overrides (max 50). null keeps existing, empty list wipes all model-level limits. |
| providerBudgets | array | Per-provider budget overrides (max 50). null keeps existing, empty list wipes all provider-level limits. |
Notes
- The request body must not be empty
- Only non-null top-level fields are applied; all others are preserved
- Field bounds are enforced identically to the manager UI settings screen (backward-compat invariant)
- USD budget price check: when
defaultBudget(ordefaultAnonymousBudget) carries a USD limit (monthlyBudgetUsd,usdPerHourorusdPerDay, including insidemodelBudgets/providerBudgets) and any AI proxy in the installation routes to a known model that has no input price in the model catalog, the whole update is rejected with400 Bad Request(error keyaiQuota.usdBudgetModelPriceMissing). Nothing is saved — the non-budget fields in the same request are not applied either. Add the missingpricePerMillionInputto the model catalog, or use a token-based limit. Token-only budgets are not checked.
Response
Success Response (200 OK)
Returns the full settings document after the update (same shape as the read endpoint), with effective values.
{
"status": "SUCCESS",
"resultList": [
{
"defaultBudget": {
"enabled": true,
"tokensPerHour": null,
"tokensPerMinute": null,
"tokensPerDay": null,
"tokensPerMonth": null,
"monthlyBudgetUsd": 500.00,
"usdPerHour": null,
"usdPerDay": null,
"softCapPercents": [],
"hardCapPercent": 100,
"overflowAction": "BLOCK",
"cheaperModelId": null,
"modelBudgets": [],
"providerBudgets": []
},
"defaultConnectTimeoutSeconds": 15,
"defaultStreamTimeoutSeconds": 300,
"defaultRetryCount": 2,
"maxAiRequestBodyBytes": 20971520,
"maxAiBinaryRequestBodyBytes": 52428800,
"maxAiBinaryResponseBodyBytes": 52428800,
"maxToolTurns": 8
}
],
"resultCount": 1
}
Response Fields
| Field | Type | Description |
|---|---|---|
| status | string | Response status: SUCCESS or FAILURE |
| resultList | array | List containing the single updated settings object |
| resultCount | integer | Always 1 for this singleton resource |
Error Response (400 Bad Request)
Returned on validation failure, an empty body, or when the caller lacks the ADMIN role.
{
"status": "FAILURE",
"resultMessage": "defaultConnectTimeoutSeconds must be between 1 and 300!"
}
Other possible messages:
{
"status": "FAILURE",
"resultMessage": "Request body can not be empty!"
}
{
"status": "FAILURE",
"resultMessage": "maxToolTurns must not exceed 100!"
}
{
"status": "FAILURE",
"resultMessage": "This budget sets a USD limit, but 2 model(s) it would price have no input price in the model catalog, so their cost cannot be measured and the USD limit would never apply to them: gpt-4o-mini, llama3. Set pricePerMillionInput on these models (Model Catalog, or the LLM provider's supported model row), or use a token-based limit instead."
}
{
"status": "FAILURE",
"resultMessage": "Unauthorized! Only users with ADMIN role can access this resource!"
}
Error Response (401 Unauthorized)
{
"status": "FAILURE",
"resultMessage": "Token is not valid!"
}
cURL Example
curl -X PUT \
"https://demo.apinizer.com/apiops/settings/ai-gateway" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"defaultConnectTimeoutSeconds": 15,
"defaultStreamTimeoutSeconds": 300,
"defaultRetryCount": 2,
"maxToolTurns": 8,
"defaultBudget": {
"enabled": true,
"monthlyBudgetUsd": 500.00,
"hardCapPercent": 100,
"overflowAction": "BLOCK"
}
}'
Notes and Warnings
- No license gate: This endpoint does not check the
AI_GATEWAYlicense module. The API layer of Apinizer applies no module gate at all, so an installation whose license does not name AI Gateway can read and write the global AI Gateway settings through it. System-admin authority remains the only gate. The AI Gateway screens in the Manager UI remain hidden without the module. - Admin Only:
- Only sysAdmin users (or users with the
ADMINrole) can update AI Gateway settings - A project-scoped
AI_DEVELOPMENTtoken is not sufficient
- Only sysAdmin users (or users with the
- Partial Update:
- Only non-null top-level fields are applied; omitted fields keep their stored value
- To leave a field unchanged, simply omit it from the body
- Validation Bounds:
- Bounds mirror the manager UI settings screen so both entry points enforce the same limits
maxToolTurns <= 0is a valid signal that disables the agentic tool-call loop
- Singleton:
- A single document governs the entire platform; if none exists it is created on first update
- No Secret Fields:
- This settings document carries no secret (
@SecretData) fields, so nothing is masked
- This settings document carries no secret (
Related Documentation
- Get AI Gateway Settings - Read these settings
- AI Gateway Settings API - Resource overview
- Error Handling - Error response formats