Assistiv Docs

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.

POST/v1/platforms/{platformId}/end-users/{endUserId}/budget

Creates 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

NameTypeRequiredDescription
max_usdnumberRequiredMaximum USD allowed in the period. Must be > 0.
periodstringOptional"one_time" (default), "daily", or "monthly". Controls when used_usd resets to zero.
auto_replenishbooleanOptionalIf true, max_usd resets to replenish_amount at each period boundary.Default: false
replenish_amountnumberOptionalUSD amount to restore on auto-replenish. Required if auto_replenish is true.
low_balance_thresholdnumberOptionalRemaining 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.

bash
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
  }'
json
{
  "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"}
GET/v1/platforms/{platformId}/end-users/{endUserId}/budget

Retrieves an end user's budget with computed remaining_usd. Platform-key response includes raw USD fields for admin visibility.

Auth: Platform key.

bash
curl https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
  -H "Authorization: Bearer sk-plat_your_key"
PATCH/v1/platforms/{platformId}/end-users/{endUserId}/budget

Updates an end user's budget configuration. Writes a type='adjustment' ledger row.

Auth: Platform key.

Request Body (all optional)

NameTypeRequiredDescription
max_usdnumberOptionalUpdated USD cap. Must be > 0.
periodstringOptional"one_time", "daily", or "monthly".
auto_replenishbooleanOptionalEnable/disable auto-replenish.
replenish_amountnumberOptionalUpdated replenish amount (USD).
low_balance_thresholdnumberOptionalUpdated alert threshold (USD).
is_activebooleanOptionalActivate or deactivate the budget.
is_suspendedbooleanOptionalTemporarily 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.
reasonstringOptionalAudit breadcrumb (max 500 chars). Flows into the ledger row and webhook payload.
metadataobjectOptionalArbitrary 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).

bash
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_..." }
  }'
bash
# 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" }'
DELETE/v1/platforms/{platformId}/end-users/{endUserId}/budget

Soft-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.

bash
curl -X DELETE https://api.assistiv.ai/v1/platforms/{platformId}/end-users/{endUserId}/budget \
  -H "Authorization: Bearer sk-plat_your_key"
POST/v1/platforms/{platformId}/end-users/{endUserId}/budget/topup

Adds 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

NameTypeRequiredDescription
amount_usdnumberRequiredUSD amount to add to the budget. Must be > 0.
reasonstringOptionalAudit breadcrumb (e.g. 'promo_grant', 'stripe_invoice').
metadataobjectOptionalArbitrary 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.

bash
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" }
  }'
json
{
  "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"}
}
POST/v1/platforms/{platformId}/end-users/{endUserId}/budget/debit

Manually 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

NameTypeRequiredDescription
amount_usdnumberRequiredUSD amount to debit. Must be > 0.
reasonstringOptionalAudit breadcrumb (e.g. 'chargeback', 'refund_adjustment').
metadataobjectOptionalArbitrary 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.

bash
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" }
  }'
json
{
  "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"}
}
GET/v1/platforms/{platformId}/end-users/{endUserId}/budget/transactions

Paginated ledger of every state change to a user's budget. Use for audit trails, monthly statements, and cost reconciliation.

Auth: Platform key.

Query Parameters

NameTypeRequiredDescription
sincestring (ISO 8601)OptionalReturn rows strictly after this timestamp. Use for incremental reconciliation.
limitintegerOptionalMax rows to return. Range: 1-200.Default: 50
bash
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"
json
{
  "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.

GET/v1/platforms/{platformId}/budgets

List all end-user budgets on the platform.

Auth: Platform key. Returns the standard paginated shape.

bash
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.

GET/v1/me/budget

Returns 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.

bash
curl https://api.assistiv.ai/v1/me/budget \
  -H "Authorization: Bearer sk-eu_your_key"
json
{
  "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.