Update an API key
Update supplied key configuration fields and preserve omitted fields
Note for users in mainland China: Please use https://api.toapis.cn as the API endpoint (Base URL). Replace https://api.toapis.com with https://api.toapis.cn in the examples in this document.
Behavior
Updates a given key's configuration, for example to adjust its name, limits, status, or expiry. The body must contain at least one field.
Name, model allowlist, daily/monthly limits, unlimited, remaining credits, status, and expiry are supported, and omitted fields keep their current values.
Enablement and status
- Changing configuration alone does not re-enable the key.
- When the same request explicitly sets
status=enabled, the updated expiry,unlimited, and credits are validated together: an expired key or a limited key whose credits are exhausted cannot be enabled and returns 409. - A revoked key returns 404.
- Omitting
statusleaves the persisted status unchanged:disabled/expired/exhaustedkeys do not recover from other field updates; a persistedenabledkey derives its read status from credits and expiry and may return toenabledafter the update.
Validation and writes
- Amount fields follow the same validation as create: JSON numbers and values that cannot be converted exactly are rejected.
model_limitsas[]clears model restrictions; daily/monthly limits set tonullor"0"clear the limit without resetting the used counters.- Setting
remaining_creditsoverwrites the remaining quota stored in the database, and later charges and refunds continue from the new value; batched charges already incurred but not yet persisted still apply afterwards. - Updates do not change accumulated usage or the account balance.
- If any field fails validation, the whole request is rejected without partial writes; the update runs in a transaction that validates the final configuration and writes only explicitly provided fields.
- Cache invalidation and in-flight request boundaries behave as before.
Authentication
AuthorizationstringheaderrequiredUse Bearer YOUR_SYSTEM_ACCESS_TOKEN. Model keys are not accepted and X-User-Id is not required. See access rules.
Request parameters
api_key_idstringpathrequiredDecimal string ID of your ordinary model key, not the sk- secret.
A nonempty body requires Content-Type: application/json and is limited to 16384 bytes. It must be a JSON object. Unknown or duplicate fields and query parameters are rejected. Write bodies have a 10-second read deadline.
statusstringbodyOnly enabled or disabled. expired, exhausted, and deleted are read-only states.
expires_atstring | nullbodyA future RFC 3339 timestamp; fractional seconds round upward. null or omission on create means no expiry. Omission on update preserves the value.
namestringbodyOptional name; when supplied, trim whitespace and require a nonempty value of at most 50 UTF-8 bytes.
model_limitsarraybodyReplace the entire model allowlist. [] clears restrictions; null is rejected. Trim each item, reject empty items and commas, and deduplicate in first-seen order. The comma-joined value is limited to 1024 UTF-8 bytes.
daily_limit_creditsstring | nullbodyDaily credit limit. null or the string "0" means no limit.
monthly_limit_creditsstring | nullbodyMonthly credit limit. null or the string "0" means no limit.
unlimitedbooleanbodyBoolean; null is rejected. Switching to false while omitting remaining_credits preserves the stored quota snapshot, which may be exhausted. Does not automatically enable the key.
remaining_creditsstring | nullbodySet absolute remaining credits, not an increment. With final unlimited=false, only a nonnegative decimal string is accepted; with true, only omission or null is allowed. Omission keeps the stored quota unchanged; null does not clear the quota stored on an unlimited key.
allow_ipsarraybodySource IP allowlist for this model API key only. A string array of individual IPv4/IPv6 addresses, trimmed, normalized, and deduplicated. [] clears restrictions; null or invalid addresses return 400. CIDR, hostnames, ports, and IPv6 zones are not supported. Omission on PATCH preserves the current value.
Request examples
requestExample
curl --request PATCH \
--url 'https://api.toapis.com/api/v1/api-keys/43' \
--header 'Authorization: Bearer YOUR_SYSTEM_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"status": "disabled"}'import requests
response = requests.patch(
"https://api.toapis.com/api/v1/api-keys/43",
headers={"Authorization": "Bearer YOUR_SYSTEM_ACCESS_TOKEN"},
json={'status': 'disabled'},
timeout=30,
)
response.raise_for_status()
print(response.json())const response = await fetch("https://api.toapis.com/api/v1/api-keys/43", {
method: "PATCH",
headers: { Authorization: "Bearer YOUR_SYSTEM_ACCESS_TOKEN", "Content-Type": "application/json" },
body: JSON.stringify({"status": "disabled"}),
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(await response.json());Response fields
Examples use fictitious data. See Get API key for key metadata and Access for the shared response and error contract.
Response examples
responseExample
{
"code": 0,
"message": "",
"data": {
"id": "43",
"name": "Example Key",
"key_hint": "****xyz9",
"status": "disabled",
"created_at": "2026-11-01T08:00:00Z",
"expires_at": "2027-01-01T00:00:00Z",
"unlimited": false,
"remaining_credits": "500",
"daily_limit_credits": null,
"monthly_limit_credits": null,
"model_limits": [],
"allow_ips": []
}
}