Skip to main content
Use the Spend Limits API to set an inference budget in USD for the current UTC day, calendar month, or both. Limits apply to the authenticated user’s organization, or their own account if they do not belong to an organization. Within that total, individual API keys can have their own API key limits. Limits are shared across the organization. Reading or changing them requires the caller’s access policy to permit the corresponding Spend Limits operation. An API key without the required permission receives HTTP 403, even when the organization has shared limits. This authorization error is separate from the HTTP 403 returned by inference requests when a spending limit blocks usage.

Which usage counts

The limit is shared across the account’s billable inference usage, including LLM requests made by voice assistants. It is not a separate budget for each assistant or model. To cap the spend of one API key, add an API key limit within the total limit. BYOK refers to the third-party provider key, not the Telnyx API key used to authenticate a request. Supplying a provider key does not exempt usage of a Telnyx-hosted model. BYOK and customer-endpoint requests remain available when billable inference is blocked. If they fall back to a billable model, the fallback is checked against the account’s block state. This limit covers costs recorded under the inference billing product, not every charge associated with a voice call. A voice assistant using BYOK can still incur other Telnyx charges.

Understand enforcement

The daily and monthly limits are independent. Exceeding either limit blocks new billable Chat Completions, Responses, Anthropic Messages, and classification requests. Requests already running finish normally. Voice-assistant LLM requests are subject to the same enforcement. An in-flight model request can finish, but a subsequent request or conversation turn can be refused after the block takes effect.
  • Spend must be strictly greater than the limit to trigger a block. A zero limit blocks at the first cent of spend; it does not disable inference before any spend occurs.
  • Daily periods reset at 00:00 UTC the next day. Monthly periods reset at 00:00 UTC on the first day of the next month.
  • Spend can lag actual usage by several minutes. After spend is recorded, a block appears within about two minutes for daily limits or ten minutes for monthly limits. Usage can exceed the configured amount before enforcement takes effect.
  • Creating or changing a limit checks existing spend immediately. Setting a limit below current spend can block inference at once.

Monitor spend in the portal

Use the Inference dashboard to investigate LLM token usage and reported cost by model and use case, including voice-assistant inference. BYOK can produce token activity without a corresponding Telnyx LLM charge. Use Billing → Spending limits to view account-wide spend against the daily and monthly caps and edit limits across supported products.
The Billing limit counters use the current UTC day and calendar month and include the whole inference billing product. The dashboard charts show LLM records and honor the selected dates, timezone, models, and use cases. Their totals can differ from the limit counters. Use spend_usd and blocked from GET /v2/spend_limits, also shown in the limit controls, to inspect the spend and block state used for enforcement. Reporting and enforcement can lag usage.

Read current limits and spend

Set TELNYX_API_KEY to an API key for the account being managed. Call List spend limits:
The unpaginated data array includes each supported product and period, even when no limit is set. Select entries with product: "inference"; use the returned products rather than assuming future product support. These top-level fields describe the total limit; blocked means the whole account is blocked. Each entry also carries credential_limits for API key limits, and credential_id, which is always null on list entries. A limit with origin: "operator" was set by Telnyx support. It can be updated or deleted through the same API. limit: null and a configured limit with unlimited: true both mean no cap for inference, but only the latter is an existing resource that can be updated.

Create a limit

When the selected entry has limit: null, call Create a spend limit. This example sets a daily limit of USD 100:
To also set a monthly limit, send a separate request with this body:
Send amount as a nonnegative JSON number. Response amounts are decimal strings. The optional audit reason accepts up to 500 characters. Send the period explicitly; the default is daily. Creation returns HTTP 409 if a limit already exists. Re-read the limits and update the existing resource instead.

Change an existing limit

Call Update a spend limit. The product is a path parameter and the period is a query parameter, not a body field. This example raises the daily limit to USD 250:
To keep an existing monthly resource but explicitly remove its cap, send {"unlimited":true} to PATCH /v2/spend_limits/inference?period=monthly. Send exactly one of amount and unlimited: true. Unknown body fields are rejected with HTTP 400. An update returns HTTP 404 if no limit exists; re-read the limits before creating one.

Remove a limit

Call Delete a spend limit for the intended period:
Inference has no default limit. Deletion returns limit: null, makes that period unlimited, and lifts its block. It does not remove the other period’s limit or block. Deleting a missing limit returns HTTP 404.

Verify a change and recover blocked requests

Create, update, and delete responses include data.evaluation:
Write responses always carry blocked: false. Use evaluation for the immediate result, then call GET /v2/spend_limits again to read the current block state for both periods. Do not treat a successful write or evaluation.released alone as confirmation that inference is unblocked.
Blocked inference requests return HTTP 403 with error code 10039 and title Inference spend limit reached. Stop automatic retries for this error. Inspect both limits, then raise the blocking limits above current spend, remove them, or wait until their UTC periods end. Verify both periods are unblocked before resuming requests. Other HTTP 403 errors can have different causes. A request refused only because its API key is blocked has a different title; see Requests from a blocked API key.

Limit individual API keys

An API key limit caps the inference spend made with one API key in a daily or monthly period. It applies within the total limit:
  • When a key’s spend in the period goes above its own limit, inference requests authenticated with that key are blocked until the period ends. The account’s other API keys keep working.
  • The total limit still covers every key. When the account is blocked, all keys are refused.
  • Daily and monthly API key limits are independent. Blocking follows the same rules and timing as the total limit; see Understand enforcement.
Name the key with credential_id: the identifier of the API key as Telnyx records it on usage. Never send the key’s secret. The identifier is matched exactly as given, without trimming or case folding. A value that matches no usage, such as a full API key, is accepted but never counts any spend. A blank value, a value longer than 255 characters, or one that contains control characters is refused with HTTP 400 and the title Invalid credential_id.
Only language-model requests authenticated with an API key record that key’s identifier, so only they count toward an API key limit. Usage without an API key identifier, including LLM requests made by voice assistants and inference usage other than language models, counts toward the total limit only.

API key limits and the total limit

When a period has a total limit with an amount, each API key limit of that period can be at most the total. API key limits are not shares of the total: together they may add up to more than it. With a total of USD 100, three keys can each have a limit of USD 99, and the total still blocks the whole account once the account’s spend exceeds USD 100. No total limit, or an unlimited total, leaves API key limits unrestricted. Limits of different periods are never compared. A refused change returns HTTP 400 with the title Limit exceeds the total limit, and its detail states the largest amount an API key limit can have, or the smallest amount the total can have. If Telnyx support lowers a total below an API key limit, that key’s credential_limits[].exceeds_total is true; the key’s limit can then be kept or lowered but not raised. An API key limit of 0 blocks the key at its first cent of spend.

Set, change, and remove an API key limit

Add credential_id to the body of Create a spend limit:
An API key limit always has an amount; unlimited is refused with HTTP 400. A key without an API key limit is limited only by the total. Without credential_id, or with credential_id: null, the request sets the total limit. An empty credential_id is refused; it never means the total limit. Creation returns HTTP 409 if the key already has a limit for the period. Each product and period accepts at most 100 API key limits. To change or remove the limit of one key, pass credential_id as a percent-encoded query parameter to Update a spend limit or Delete a spend limit:
Deleting an API key limit lifts that key’s block in that period at once. It does not remove the key’s limit or block in the other period: a key that is also blocked under its other-period limit stays blocked until that block ends too, so check evaluation.still_blocked_other_period before resuming requests with the key. Deleting the total limit leaves the API key limits in place. Write responses for an API key carry its credential_id (null for a total limit write). Their evaluation describes that key: still_blocked_other_period refers to the key’s limit in the other period, and account_blocked is true when the account itself stays blocked under a total limit.

Read API key limits

GET /v2/spend_limits returns API key limits nested in the entry of their product and period: A key’s block appears only in credential_limits. The top-level blocked stays false unless the whole account is blocked.

Requests from a blocked API key

Inference requests authenticated with a blocked API key return HTTP 403 with error code 10039 and title API key spend limit reached. The detail names the key, states when it resumes at the latest, and confirms that the account’s other API keys are not affected. Stop automatic retries for this key. Raise or remove the key’s blocking limits, or wait until their periods end, and verify that the key is unblocked in both periods before resuming requests with it; other keys can keep sending requests. When the whole account is blocked, every key receives the Inference spend limit reached error described above. If the key’s own block ends later than the account’s, the detail names the key and gives the later time.