Bundled LLM
Driftstack’s bundled LLM rail lets customers run AI-driven agent sessions without supplying their own Anthropic API key. Driftstack hosts the decomposer + bills usage against a customer-controlled monthly soft cap (default $20).
Opt-in is explicit (consent: true) and revocable; the soft cap is
customer-configurable up to a $10,000/month ceiling. The agent
session route’s resolution chain prefers BYOK
(per-request header or stored) over bundled-LLM — bundled-LLM is
the no-BYOK fallback.
Activation: the settings + status routes are always registered (the
bootstrap wires a BundledLlmService by default), so they don’t
return a 503 stub. Consent and budget enforcement surface as 402
at agent-session turn time (see below); any 503 you encounter is
likewise returned on the agent-session turn route, not on these
settings/status reads.
Resource shape
The bundled-LLM settings record:
{
"consent": true,
"monthly_cap_usd_cents": 2000
}
The bundled-LLM status record (settings + month-to-date spend):
{
"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"
}
Note the status record names the cap cap_cents (the settings
record uses monthly_cap_usd_cents — same value, different field
name per surface). remaining_cents is max(0, cap_cents − used_this_month_cents). month_started_at is the UTC
calendar-month boundary so the dashboard can render “resets on
<date>” without re-deriving it.
used_this_month_cents sums usage_records.cost_usd_cents over
the rows where record_type = 'agent_decomposer_bundled' and
recorded_at >= start_of_calendar_month (UTC).
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” / “raise your cap” CTA; that field is derived from real spend.
Get current settings
GET /v1/account/me/bundled-llm-settings
Returns the settings record. Defaults to
{ consent: false, monthly_cap_usd_cents: 2000 } for accounts
that have never PATCHed.
Requires broad read (or account_owner). Resource-granular,
write-only, and zero-scope keys cannot inspect billing consent or cap.
Get current status (settings + spend)
GET /v1/account/me/bundled-llm-status
Returns the status record above. The dashboard’s
BundledLlmStatusPanel reads this on page-load to render consent,
cap, used spend, and remaining budget.
Requires the same broad read scope because the response includes
account-wide month-to-date spend and remaining budget.
Update settings (PATCH)
PATCH /v1/account/me/bundled-llm-settings
The same controls are live in the desktop app under Settings → AI & billing. The desktop form and this endpoint update the same consent and monthly-cap record.
Partial update — either field may be omitted, but at least one of
consent / monthly_cap_usd_cents must be present. An empty body
is rejected with 400 (it carries no change to apply).
Request body:
{
"consent": true,
"monthly_cap_usd_cents": 5000
}
Constraints:
consent— boolean.monthly_cap_usd_cents— integer; 0 to 1,000,000 ($10,000 ceiling). Negative values rejected with400.
Tier availability. Opting in (
consent: true) requires a tier that offers bundled-LLM billing: API Builder, API Scale, or Enterprise. On BYOK-only tiers (Team, Agency, API Starter) — and on tiers without the AI agent at all — the opt-in is refused with a 403forbiddentier error. Opting out (consent: false) and cap-only updates are accepted on every tier, so a downgraded account can always switch bundled billing off. BYOK key management (/v1/account/me/byok-anthropic) is not tier-gated beyond the AI-agent tiers themselves.
Response (200) is the post-update settings record:
{
"consent": true,
"monthly_cap_usd_cents": 5000
}
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": "Spend this month has reached the configured cap.",
"spent_cents": 2000,
"cap_cents": 2000
}
Recovery paths surfaced in the problem-detail string:
- Raise the cap via
PATCH /v1/account/me/bundled-llm-settings - Supply a BYOK key via the
x-byok-anthropic-api-keyheader orPUT /v1/account/me/byok-anthropic-key - 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 has bundled-LLM wired 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": "Opt in via PATCH /v1/account/me/bundled-llm-settings."
}
The SDK exposes the typed BundledLlmConsentRequiredError (no
extension fields).
Errors
| Status | Type | When |
|---|---|---|
| 400 | validation | body fails schema (negative cap, > 1_000_000 cap) |
| 401 | unauthorized | missing or invalid bearer token |
| 403 | forbidden | consent: true on a tier without bundled-LLM billing (below API Builder) |
| 402 | bundled-llm-budget-exhausted | spend reached the cap; recover via PATCH / BYOK / next month |
| 402 | bundled-llm-consent-required | deployment has bundled-LLM but the customer hasn’t opted in |
The settings + status routes above do not return a 503. A 503
for an unwired bundled-LLM service is returned on the agent-session
turn route, not on these reads.
Privacy + billing
- Bundled-LLM costs are billed alongside the customer’s tier
subscription. Standard API Builder and API Scale usage posts a
flat $0.10 per agent turn, independent of model choice and
token count; Enterprise can use a contracted custom rate. The
recorder stores the posted per-call amount in cents with
cost_basis = 'bundled_flat_per_turn'for auditability. It does not expose Driftstack’s upstream provider cost. - 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.