Prevent Overspend
An AI agent can make hundreds of model calls a minute, and one customer can run dozens of agents at once. Every one of them draws on the same credit balance. If your integration checks the flag before an action and tracks usage after it, the balance is only enforced one action at a time, and agents running in parallel walk straight past it.
A company with 1,000 credits starts six agent runs at once, each budgeted at up to 200 credits. Each run checks the flag, sees 1,000 credits, and starts. Between them they can spend 1,200 credits against a balance of 1,000, and nothing in a plain check could have stopped it, because none of the six had tracked anything yet when the others checked.
Schematic closes that gap and the others like it from your backend. Each control below stops a different way a balance gets overrun, and they stack.
Everything on this page runs on your server with a secret API key. The examples use the Node.js SDK. The other backend SDKs support the same checks and reservations, and each SDK reference shows its method names.
Size every check
A plain flag check asks whether the company has access right now. For a credit-metered feature, it prices the check at one unit of the feature’s consumption rate. A company with 10 credits left passes a check for an action that will cost 5,000.
Pass the size of the action with the check, and Schematic evaluates the flag as if that usage had already happened. This is a preflight. Nothing is reserved or consumed, and your app still tracks usage when the work finishes.
Size the preflight as an upper bound for the work. The SDK rounds a fractional quantity up, so a check never passes on less usage than the action records.
The same check gives you what you need to show the customer the price before they commit. The entitlement in the response carries the feature’s consumptionRate and the company’s balance, so the estimate is the quantity times the rate:
Read creditSettled for anything a customer sees. It changes only when work completes, so it holds steady while other runs have credits reserved. Only the flag value reflects the preflight. The entitlement figures in the response are the company’s current balance, not the balance after the action.
Preflight values are whatever the caller sends, and an undersized value can let through a check that the real size would fail. Compute the size on your server from the work you are about to run, never from a value a browser passed you.
Preflight is not limited to credits. It works against any numeric limit a flag evaluates, including event-based allowances and trait-based limits such as seats. See Preflight checks.
Reserve before the work runs
A preflight tells you whether the action fits the balance now. It does not stop five other runs from using the same credits before this one finishes. To close that gap, reserve the credits when you check.
Configure creditLeases on the client, and check takes a reservation whenever you pass usage and the feature is credit-metered. The reserved credits leave the drawable balance at check time, so the next run to check sees what this one is about to spend. When the work finishes, settle the reservation with what it actually used, and the rest goes back to the balance.
Back to the six runs against 1,000 credits. With reservations, the first five each reserve 200 and start. The sixth is refused, because the five open reservations hold the whole balance. As each run settles, its unused credits return, and a later check can use them.
A few things to plan around:
- A reservation is all or nothing. A check is refused when the balance cannot fund the full amount, and nothing is consumed.
- Set the reservation lifetime above your longest run. An unsettled reservation expires after
defaultReservationTTL, 60 seconds by default, and its credits return to the balance. Without DataStream the API holds a reservation for at most one hour. A settle that arrives late still bills the usage once. - Track what the check did not reserve. A check allows without a reservation when the feature is not credit-metered or the check failed open, and that usage still has to be tracked.
- A check that cannot reserve fails closed. When the API is unreachable or the balance cannot be reserved against,
allowedis false. PassonAcquireFailure: "fail-open"on a check where a denial is worse than letting the work through. Without DataStream, fail-open returns the flag’s default value, so passdefaultValue: truewith it.
Without DataStream, the SDK makes one check-and-reserve call to the API per check. With DataStream enabled, it holds a block of credits locally and reserves out of it, so a check needs no network round trip. Across several processes, that mode needs a shared Redis so every process reserves against the same block. Calling the API without an SDK, use check and reserve and settle with a track event that carries the reservation_id. Credit Leases and Reservations covers both modes and every endpoint.
Long-running and multi-step work
A reservation covers one operation and settles on the first track. For a workflow with several steps, or a batch job you can estimate up front, acquire a lease for the whole job instead. You commit usage after each step as its cost becomes known, extend the lease if the job needs more than the estimate, and release what is left at the end. See Leases.
Cap the size and rate of spend
A balance limits how much a company spends in total. Usage controls limit how fast it spends, and who spends it. Add policies on the company’s Entitlements tab under Usage Control, or through the API.
Policies stack, and a check has to fit every one that applies as well as the balance. A refused check returns false with a reason that names the policy, such as A draw of 2000 credits exceeds the company limit of 500 credits per request, and your app handles it the same way it handles an empty balance.
A per-draw limit can only refuse a request whose size it knows. A check with no preflight is priced at a single unit, so it almost never trips a per-draw limit. Pass the size on every check for a feature that has one, whether through a preflight or a reservation.
A per-user limit counts only the draws attributed to that user, so send user with every check and track an agent makes. Give each agent its own user rather than sharing one across a fleet. See Seat and Agent Budgets.
Decide what happens at zero
Every credit grant has a policy for an empty balance. Block usage stops credit-metered features at zero. Automatic and user-controlled top-ups buy more credits before the balance runs out. Bill in arrears lets usage continue and invoices it afterward.
Under bill in arrears, set an Overdraft Limit on the credit grant. It caps how far the balance can go below zero before the company is blocked, which caps how much unpaid usage one account can build up between invoices. See Handling Empty Credit Balances.
Warn before the limit
Two webhook events fire as a company draws down its balance: credit.limit.warning at 80% and credit.limit.reached at 100%. Wire both to an internal alert and to a message the customer sees, so a stopped agent is never the first sign of a problem. See Entitlement & Credit Trigger Webhooks.
To show customers their own limits, Check flags returns the usage control policies that apply to a company and user in credit_spend_policies, with how much each has spent in the current period and when it resets.
Related
- Credit Leases and Reservations covers how reservations and leases hold credits, every endpoint, and the SDK settings.
- Usage Controls covers per-draw, hourly, daily, and per-user policies.
- Preflight checks covers preflight against any numeric limit, not just credits.
- Seat and Agent Budgets covers attributing draws to users and agents and reporting on them.
- Handling Empty Credit Balances covers what happens when the balance reaches zero.