Budgets
USD-based budgets that control how much each end user can spend. Budgets support one-time, daily, and monthly periods with optional auto-replenishment. Budget checks happen before every inference request. Every budget mutation is recorded in a full transaction ledger for audit and reconciliation.
/v1/platforms/{platformId}/end-users/{endUserId}/budgetCreates a USD budget for an end user. Atomically writes an opening-balance ledger row so GET /budget/transactions shows the budget's full history from creation.
Auth: Platform key.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| max_usd | number | Required | Maximum USD allowed in the period. Must be > 0. |
| period | string | Optional | "one_time" (default), "daily", or "monthly". Controls when used_usd resets to zero. |
| auto_replenish | boolean | Optional | If true, max_usd resets to replenish_amount at each period boundary.Default: false |
| replenish_amount | number | Optional | USD amount to restore on auto-replenish. Required if auto_replenish is true. |
| low_balance_threshold | number | Optional | Remaining USD threshold for the budget.low_balance webhook event (edge-triggered). Must be >= 0. |
ℹAuto-budget on user creation
Set settings.default_budget_usd on your platform to automatically create a monthly budget for every new end user. See Platforms.
curl -X POST https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
-H "Authorization: Bearer sk-plat_your_key" \
-H "Content-Type: application/json" \
-d '{
"max_usd": 10.00,
"period": "monthly",
"auto_replenish": true,
"replenish_amount": 10.00,
"low_balance_threshold": 1.00
}'{
"id": "uuid",
"platform_id": "uuid",
"end_user_id": "uuid",
"max_usd": 10.00,
"used_usd": 0.00,
"remaining_usd": 10.00,
"period": "monthly",
"period_start": "2026-04-01T00:00:00Z",
"auto_replenish": true,
"replenish_amount": 10.00,
"low_balance_threshold": 1.00,
"is_active": true,
"is_suspended": false,
"created_at": "2026-04-08T10:30:00Z",
"updated_at": "2026-04-08T10:30:00Z"}/v1/platforms/{platformId}/end-users/{endUserId}/budgetRetrieves an end user's budget with computed remaining_usd. Platform-key response includes raw USD fields for admin visibility.
Auth: Platform key.
curl https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
-H "Authorization: Bearer sk-plat_your_key"/v1/platforms/{platformId}/end-users/{endUserId}/budgetUpdates an end user's budget configuration. Writes a type='adjustment' ledger row.
Auth: Platform key.
Request Body (all optional)
| Name | Type | Required | Description |
|---|---|---|---|
| max_usd | number | Optional | Updated USD cap. Must be > 0. |
| period | string | Optional | "one_time", "daily", or "monthly". |
| auto_replenish | boolean | Optional | Enable/disable auto-replenish. |
| replenish_amount | number | Optional | Updated replenish amount (USD). |
| low_balance_threshold | number | Optional | Updated alert threshold (USD). |
| is_active | boolean | Optional | Activate or deactivate the budget. |
| is_suspended | boolean | Optional | Temporarily pause inference without losing budget state. While suspended: inference returns 402 budget_suspended, but topups and manual debits still work. Fires budget.suspended / budget.unsuspended webhooks. |
| reason | string | Optional | Audit breadcrumb (max 500 chars). Flows into the ledger row and webhook payload. |
| metadata | object | Optional | Arbitrary JSON metadata. Flows into the ledger row and webhook payload. |
ℹIdempotency-Key header
PATCH honors Idempotency-Key. Same key + same body replays the cached ledger row. Same key + different body returns 409 Conflict.
ℹSuspension vs deactivation
Use is_suspended for temporary pauses (abuse review, failed payment). Use DELETE /budget for permanent removal (account cancellation, GDPR erasure).
curl -X PATCH https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
-H "Authorization: Bearer sk-plat_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: upgrade-user123-2026-04" \
-d '{
"max_usd": 20.00,
"auto_replenish": true,
"replenish_amount": 20.00,
"reason": "upgrade_to_pro",
"metadata": { "stripe_subscription_id": "sub_..." }
}'# Suspend a user (blocks inference, keeps budget queryable)
curl -X PATCH https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
-H "Authorization: Bearer sk-plat_your_key" \
-H "Content-Type: application/json" \
-d '{ "is_suspended": true, "reason": "abuse_review" }'
# Un-suspend
curl -X PATCH ... \
-d '{ "is_suspended": false, "reason": "review_cleared" }'/v1/platforms/{platformId}/end-users/{endUserId}/budgetSoft-deletes the user's budget (flips is_active to false). Writes a ledger row so the audit trail survives. The user then spends freely against the platform wallet until you recreate one.
Auth: Platform key. Returns 204 No Content.
curl -X DELETE https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
-H "Authorization: Bearer sk-plat_your_key"/v1/platforms/{platformId}/end-users/{endUserId}/budget/topupAdds USD to an end user's budget (increases max_usd). Use for one-time credit grants or add-on purchases.
Auth: Platform key.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| amount_usd | number | Required | USD amount to add to the budget. Must be > 0. |
| reason | string | Optional | Audit breadcrumb (e.g. 'promo_grant', 'stripe_invoice'). |
| metadata | object | Optional | Arbitrary JSON. Stored on the ledger row. |
⚠Idempotency-Key (strongly recommended)
Same key + same body returns the cached ledger row (no double-credit). Same key + different body returns 409 Conflict. Use a key stable across retries (Stripe invoice ID, your internal payment ID). No key means every call applies.
curl -X POST https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget/topup \
-H "Authorization: Bearer sk-plat_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: stripe-invoice-in_1Mt2P3xyz" \
-d '{
"amount_usd": 5.00,
"reason": "promo_grant",
"metadata": { "promo_code": "WELCOME10" }
}'{
"success": true,
"idempotent_replay": false,
"budget_id": "uuid",
"max_usd": 15.00,
"used_usd": 1.50,
"transaction": {
"id": "txn-uuid",
"type": "topup",
"amount_usd": 5.00,
"max_usd_after": 15.00,
"used_usd_after": 1.50,
"reason": "promo_grant",
"metadata": { "promo_code": "WELCOME10"},
"created_at": "2026-04-09T12:00:00Z"}
}/v1/platforms/{platformId}/end-users/{endUserId}/budget/debitManually debit USD from a user's budget (increases used_usd). Use for chargebacks, refunds, manual write-offs, or batch reconciliation.
Auth: Platform key.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| amount_usd | number | Required | USD amount to debit. Must be > 0. |
| reason | string | Optional | Audit breadcrumb (e.g. 'chargeback', 'refund_adjustment'). |
| metadata | object | Optional | Arbitrary JSON. Stored on the ledger row. |
ℹNegative balances allowed
Unlike inference debits (which gate on remaining_usd > 0), manual debits do NOT refuse when the user has insufficient balance. This lets you record chargebacks that push a user into debt. Inference still blocks at remaining_usd <= 0.
ℹBypasses suspension
Manual debits work on suspended users. You can record chargebacks against a suspended account. Same Idempotency-Key contract as topup.
curl -X POST https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget/debit \
-H "Authorization: Bearer sk-plat_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: chargeback-du_1Mt..." \
-d '{
"amount_usd": 5.00,
"reason": "chargeback_dispute_du_1Mt...",
"metadata": { "dispute_id": "du_1Mt...", "chargeback_date": "2026-04-11" }
}'{
"success": true,
"idempotent_replay": false,
"budget_id": "uuid",
"max_usd": 10.00,
"used_usd": 12.00,
"transaction": {
"id": "txn-uuid",
"type": "debit",
"amount_usd": 5.00,
"max_usd_after": 10.00,
"used_usd_after": 12.00,
"reason": "chargeback_dispute_du_1Mt...",
"metadata": { "dispute_id": "du_1Mt..."},
"created_at": "2026-04-11T15:00:00Z"}
}/v1/platforms/{platformId}/end-users/{endUserId}/budget/transactionsPaginated ledger of every state change to a user's budget. Use for audit trails, monthly statements, and cost reconciliation.
Auth: Platform key.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| since | string (ISO 8601) | Optional | Return rows strictly after this timestamp. Use for incremental reconciliation. |
| limit | integer | Optional | Max rows to return. Range: 1-200.Default: 50 |
curl "https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget/transactions?since=2026-04-01T00:00:00Z&limit=50" \
-H "Authorization: Bearer sk-plat_your_key"{
"data": [
{
"id": "txn-uuid",
"budget_id": "uuid",
"type": "opening",
"amount_usd": 2.00,
"max_usd_before": 0.00,
"max_usd_after": 2.00,
"used_usd_before": 0.00,
"used_usd_after": 0.00,
"reason": "budget_created",
"metadata": {},
"actor_key_id": "apk_xxx",
"actor_type": "platform_key",
"created_at": "2026-04-08T10:30:00Z"},
{
"id": "txn-uuid-2",
"type": "topup",
"amount_usd": 1.00,
"max_usd_before": 2.00,
"max_usd_after": 3.00,
"used_usd_before": 0.00,
"used_usd_after": 0.00,
"reason": "promo_grant",
"metadata": { "promo_code": "WELCOME10"},
"created_at": "2026-04-09T12:00:00Z"},
{
"id": "txn-uuid-3",
"type": "debit",
"amount_usd": 0.25,
"max_usd_after": 3.00,
"used_usd_after": 0.25,
"reason": null,
"metadata": { "model": "gpt-4o-mini", "input_tokens": 120 },
"actor_type": "end_user_key",
"created_at": "2026-04-09T12:05:00Z"}
],
"limit": 50
}Transaction Types
opening
Emitted once on budget creation via POST /budget.
topup
Platform tops up via POST /budget/topup. Includes promo grants and Stripe invoices.
debit
Manual debit via POST /budget/debit OR automatic on each inference call.
adjustment
Config changes via PATCH /budget, soft-delete via DELETE /budget, suspension flips, and daily/monthly period resets.
Rows include actor_type (platform_key, end_user_key, system) and actor_key_id so you can see exactly who/what made each change.
/v1/platforms/{platformId}/budgetsList all end-user budgets on the platform.
Auth: Platform key. Returns the standard paginated shape.
curl "https://api.assistiv.ai/v1/platforms/{platformId}/budgets?page=1&limit=20" \
-H "Authorization: Bearer sk-plat_your_key"End-User Budget Endpoint
End users query their own budget with their sk-eu_* key. Returns display values only — no raw USD exposed. See Self-Service for more /v1/me/* endpoints.
/v1/me/budgetReturns the authenticated end user's current budget status.
Auth: End-user key. Returns 404 if no active budget exists. Returns the row even when is_suspended=true so your UI can render an "account paused" state.
curl https://api.assistiv.ai/v1/me/budget \
-H "Authorization: Bearer sk-eu_your_key"{
"id": "uuid",
"platform_id": "uuid",
"end_user_id": "uuid",
"max_usd": 10.00,
"used_usd": 1.50,
"remaining_usd": 8.50,
"period": "monthly",
"period_start": "2026-04-01T00:00:00Z",
"auto_replenish": true,
"is_active": true,
"is_suspended": false
}Period Reset Behavior
one_time
Budget never resets. Once used_usd reaches max_usd, the user is blocked until you top up or recreate the budget.
daily
used_usd resets to 0 every 24 hours from period_start. If auto_replenish is true, max_usd is also reset to replenish_amount.
monthly
Same as daily but uses calendar month boundaries. The next reset is always period_start + 1 month (calendar math, not 30 days). No cron needed — auto-replenish is built in.