Bundled LLM
Driftstack’s bundled LLM option lets customers run AI-driven agent sessions without their own Anthropic API key. Each agent turn counts a fixed amount against a monthly cap the customer controls (default $20).
Opting in, and the monthly cap (up to $100), are set by a person in the
Settings page of the Driftstack dashboard.
If there is an Anthropic key of your own — stored in the dashboard, or
sent with a request in the x-byok-anthropic-api-key header — it is
used instead of the bundled LLM.
The status read below is always available. Consent and budget
enforcement surface as typed 402 responses at agent-session turn time
(see below). If the bundled LLM is not available, a turn with no key of your
own returns 502 byok-anthropic-required; the status read stays
available.
Bundled billing is offered on the earlier API Builder and API Scale plans, and on Enterprise. On the earlier Team, Agency and API Starter plans the AI agent runs with your own Anthropic key only. Starter, Pro, Team and Scale run it on the AI credits they include each month, or on your own key. The Trial has no AI agent.
Get current status (settings + spend)
GET /v1/account/me/bundled-llm-status
Returns the consent flag, the cap and the month-to-date spend. Read it before an AI run to know whether a turn will be refused.
{
"consent": true,
"cap_cents": 2000,
"used_this_month_cents": 450,
"remaining_cents": 1550,
"refused_count_this_month": 0,
"month_started_at": "2026-05-01T00:00:00.000Z"
}
remaining_cents is max(0, cap_cents − used_this_month_cents).
month_started_at is the UTC calendar-month boundary, so you can say
when the budget resets without re-deriving it.
used_this_month_cents is the account’s total bundled-LLM spend, in
cents, on agent-session turns since the start of the current UTC
calendar month (month_started_at).
refused_count_this_month is a compatibility field and returns 0.
Refusal events (402 BundledLlmBudgetExhausted) are not persisted as
usage rows. Branch on remaining_cents <= 0 to drive a “you’ve hit the
cap” message; that field is derived from real spend.
Requires broad read (or account_owner), because the response
includes account-wide month-to-date spend and remaining budget.
Soft-cap enforcement
When the customer’s bundled-LLM spend reaches the cap, the agent session route refuses the turn with:
HTTP/1.1 402 Payment Required
Content-Type: application/problem+json
{
"type": "https://errors.driftstack.dev/bundled-llm-budget-exhausted",
"title": "Bundled-LLM monthly cap reached",
"status": 402,
"detail": "You've used $20.00 of your $20.00 monthly bundled-LLM budget. Raise the cap in the dashboard, up to the $100 maximum (it is changed there, not with an API key), supply your own Anthropic API key via PUT /v1/account/me/byok-anthropic-key, or wait for the next calendar month.",
"spent_cents": 2000,
"cap_cents": 2000
}
When the cap can still be raised, the detail says to raise it in the dashboard:
the settings route is for the dashboard only and answers 403 to any API key, whatever its scopes.
The ways out:
- Raise the cap in the dashboard’s Settings page if it is below the $100 maximum
- Send your own Anthropic key in the
x-byok-anthropic-api-keyheader, or store one in the dashboard’s Settings page - Wait for the next calendar month
The SDK exposes the typed BundledLlmBudgetExhaustedError with
.spent_cents / .cap_cents extension fields (Python:
spent_cents / cap_cents; TS: spentCents / capCents; Go:
SpentCents / CapCents).
Consent-required gate
When the deployment offers bundled-LLM but the customer hasn’t
opted in (consent: false), the agent session route refuses with:
HTTP/1.1 402 Payment Required
Content-Type: application/problem+json
{
"type": "https://errors.driftstack.dev/bundled-llm-consent-required",
"title": "Bundled-LLM consent required",
"status": 402,
"detail": "This deployment offers bundled-LLM but your account has not opted in. Turn it on in the dashboard (the setting is changed there, not with an API key), or PUT /v1/account/me/byok-anthropic-key to bring your own Anthropic key (BYOK always wins)."
}
The SDK exposes the typed BundledLlmConsentRequiredError (no
extension fields).
The detail says to turn it on in the dashboard: the settings route is for the
dashboard only and answers 403 to any API key (its field is consent, not
bundled_llm_consent). Opting in is done in the dashboard’s Settings page. On plans without
bundled billing — every plan on offer, and the earlier Team, Agency and API
Starter plans — this error does not mean “opt in”: opting in is refused on
those plans. Add your own key instead — in the dashboard’s Settings page, or
the x-byok-anthropic-api-key header on each message.
When consent is on but the account’s current plan no longer includes
bundled billing (after a downgrade, for example), the turn returns
403 forbidden instead, asking you to upgrade or add your own key.
Branch on the problem type, not on the detail text: the detail is written
for people and can change.
Models on bundled billing
Bundled billing runs the default model, Claude Sonnet 5.5, and the other
models in the picker except Opus and Fable. Claude Opus models and Claude
Fable 5.1 are available with your own Anthropic key only. When a session
would run one of them on bundled billing — because the account has no key of
its own — the request is refused with a 403:
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
{
"type": "https://errors.driftstack.dev/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Claude Opus 5 is available with your own Anthropic key. Add your key (PUT /v1/account/me/byok-anthropic-key, or the x-byok-anthropic-api-key header), or start a session with Claude Sonnet 5.5.",
"requires_own_key": true,
"model": "claude-opus-5"
}
This is checked when the session is created (for an account with no key of its own and bundled billing on) and again on every turn, because a session created with your own key moves to bundled billing if that key is removed or expires. A session using your own key keeps every model.
In the SDKs this is a ForbiddenError; read the flag from
err.extensions.requires_own_key (TypeScript),
err.problem["requires_own_key"] (Python) or
Problem["requires_own_key"] (Go).
Errors
| Status | Type | When |
|---|---|---|
| 401 | unauthorized | missing or invalid bearer token |
| 403 | forbidden | an Opus or Fable model on bundled billing (agent-session create or turn) |
| 402 | bundled-llm-budget-exhausted | spend reached the cap; raise it (if below $100), BYOK, or wait |
| 402 | bundled-llm-consent-required | deployment has bundled-LLM but the customer hasn’t opted in |
The status read above does not return a 503. When
bundled-LLM is not available on the deployment, the agent-session turn
route returns 502 byok-anthropic-required for a turn with no key of your
own; the status read keeps working.
Agent-session turns on bundled billing can also return 403 forbidden (the
plan no longer includes bundled billing) and 429 rate-limited with
retry_after_seconds: 5 (your account already has 3 turns running on bundled
billing). No step ran, so wait for one to finish and send the same message
again, Idempotency-Key and all. See
Agent sessions — Errors.
Privacy + how turns are counted
- On the earlier API Builder and API Scale plans, each agent turn counts a flat $0.10 against the customer-controlled monthly budget, whatever the model or token count. This budget is enforced by Driftstack but is not a separately itemized charge on your Stripe invoice today; Enterprise can use a contracted custom budget. The amount counted against the budget per turn is this flat value, not Driftstack’s actual provider cost. A turn refused before the model is called (a task the Acceptable Use Policy check refuses, or a session whose token budget is spent) counts nothing.
- No prompt content is logged on Driftstack’s side beyond what customers can read in their own session transcripts.
- Bundled-LLM consent does NOT grant Driftstack any rights to train models on customer prompts. The current bundled-LLM provider is Anthropic Claude; per their API terms, customer data is not used for training.