STACK
MENU
DOCS / API REFERENCE / BILLING

Billing API

A tier subscription defines monthly allowances, seats, and retention. The Wallet pays for variable-cost items such as sealed execution, identity verification, paid skills, and overage. This API reports both.

Tier allowances reset on the first of each month at 00:00 UTC. Subscriptions renew monthly from the purchase date. Wallet balance is non-expiring and non-transferable between operators.

GET /v1/billing/balance

Returns the current Wallet balance in cents and formatted US dollars.

json
{
  "balance_cents": 12400,
  "balance_usd": "$124.00"
}

GET /v1/billing/transactions

Keyset-paginated wallet transaction history. Each entry is a real credit or debit in the STACK wallet. The response does not include operator IDs, wallet hold IDs, payment IDs, prompts, responses, credentials, or audit payloads.

Query parameters

  • view - timeline to include standalone LLM calls beside wallet movements (optional)
  • entry_kind - all | wallet | llm for timeline rows (optional, default: all)
  • limit - integer 1-200 (default: 50)
  • cursor - next_cursor from the previous page (optional)
  • type - topup | refund | invocation | compute | identity | overage | adjustment (optional)
  • direction - in for credits or out for debits (optional)
  • since - inclusive ISO 8601 timestamp (optional)
  • until - exclusive ISO 8601 timestamp (optional)
json
{
  "total": 51,
  "next_cursor": "wtxn_9fA2...",
  "has_more": true,
  "transactions": [
    {
      "id": "wtxn_9fA2...",
      "type": "compute",
      "amount_cents": -3,
      "meter": "sealed_execution",
      "description": "Compute charge",
      "created_at": "2026-07-15T10:14:00Z",
      "details": {
        "skill_id": "skl_7p...",
        "invocation_id": "inv_4m...",
        "mission_id": "mis_3x...",
        "skill": { "id": "skl_7p...", "name": "Invoice review" },
        "invocation": { "id": "inv_4m...", "status": "completed" },
        "mission": { "id": "mis_3x...", "declared_intent": "Review supplier invoices" },
        "llm_sources": [
          {
            "id": "usg_1a...",
            "created_at": "2026-07-15T10:13:58Z",
            "operation": "Sealed skill execution",
            "declared_purpose": "Review supplier invoices",
            "provider": "openrouter",
            "model": "provider/model",
            "prompt_tokens": 1200,
            "completion_tokens": 300,
            "total_tokens": 1500,
            "cached_prompt_tokens": 800,
            "streaming": false,
            "allocated_microcents": 1200000,
            "agent": { "id": "agt_2k...", "name": "Support agent" },
            "mission": { "id": "mis_3x...", "declared_intent": "Review supplier invoices" },
            "skill": { "id": "skl_7p...", "name": "Invoice review" },
            "invocation": { "id": "inv_4m...", "status": "completed" },
            "sealed_step_index": 0
          },
          {
            "id": "usg_1b...",
            "created_at": "2026-07-15T10:13:59Z",
            "operation": "Sealed skill execution",
            "declared_purpose": "Review supplier invoices",
            "provider": "openrouter",
            "model": "provider/model",
            "prompt_tokens": 700,
            "completion_tokens": 200,
            "total_tokens": 900,
            "cached_prompt_tokens": null,
            "streaming": false,
            "allocated_microcents": 1400000,
            "agent": { "id": "agt_2k...", "name": "Support agent" },
            "mission": { "id": "mis_3x...", "declared_intent": "Review supplier invoices" },
            "skill": { "id": "skl_7p...", "name": "Invoice review" },
            "invocation": { "id": "inv_4m...", "status": "completed" },
            "sealed_step_index": 1
          }
        ],
        "machine_sources": [
          {
            "id": "smu_8q...",
            "created_at": "2026-07-15T10:13:59Z",
            "duration_ms": 12,
            "allocated_microcents": 400000,
            "skill": { "id": "skl_7p...", "name": "Invoice review" },
            "invocation": { "id": "inv_4m...", "status": "completed" },
            "sealed_step_index": 2
          }
        ],
        "machine_cost_microcents": 400000,
        "source_status": "recorded"
      }
    }
  ]
}

Use next_cursor unchanged on the next request. STACK returns HTTP 400 when a cursor is malformed, missing, owned by another operator, or outside the active filter window. llm_sources lists every model call that contributed to the debit. allocated_microcents gives the exact share from that call. Sealed machine cost stays separate inmachine_cost_microcents.machine_sources keeps the exact sealed invocation and script step, including a failed invocation whose remainder crosses a later wallet cent. STACK does not store prompt or response text. Older model and sealed compute charges can returnsource_status: "not_recorded". STACK does not infer a source for those rows.declared_purpose comes from the exact mission or passport. It never contains prompt or response text.

Unified Wallet timeline

Set view=timeline to return wallet movements and model calls in one stable list. The default response above does not change. The first timeline page fixes one snapshot, and each opaque cursor keeps that snapshot for the next page. Transaction type and directionfilters return wallet rows only because standalone calls are not balance movements.

json
{
  "snapshot_at": "2026-08-16T10:00:00Z",
  "next_cursor": "eyJ2IjoxLCJzIjoiLi4uIn0",
  "has_more": true,
  "rows": [
    {
      "kind": "wallet_transaction",
      "transaction": { "id": "wtxn_9fA2...", "type": "compute", "amount_cents": -3 }
    },
    {
      "kind": "llm_call",
      "call": {
        "id": "usg_1c...",
        "operation": "Gateway model call",
        "provider": "openrouter",
        "model": "provider/model",
        "total_tokens": 900,
        "price": { "state": "wallet_price", "amount_microcents": 375000 }
      }
    }
  ]
}

Calls with an exact allocation stay under their wallet transaction. A standalone call had no captured debit at the page snapshot. STACK does not link old calls by time, model, token count, or price. A standalone price is wallet_price, included, covered, or unavailable. Use microcents for display so a real sub-cent amount does not appear as zero.

POST /v1/billing/topup

Opens a Stripe Checkout session and returns the redirect URL. On successful payment, the webhook credits the wallet; poll /v1/billing/balance until the new balance appears (typically within a few seconds).

Request

json
{ "amount_cents": 5000 }
  • Minimum: 1000 ($10)
  • Maximum: 1000000 ($10,000) per session

Response

json
{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_…",
  "session_id": "cs_test_a1…"
}

POST /v1/billing/subscribe

Open Stripe Checkout for a paid subscription.

Request

json
{ "tier": "pro" }

Response

json
{ "checkout_url": "https://checkout.stripe.com/c/pay/cs_..." }

POST /v1/billing/cancel-subscription

Cancel the current subscription. The tier stays active until the end of the billing period, then drops to free.

POST /v1/billing/refund/:transactionId

Refund a top-up transaction back to the original payment method. Only available on top-up transactions less than 30 days old. The Wallet must still contain the complete top-up amount.

POST /v1/billing/seats

Set the number of paid add-on seats. The request fails if it exceeds the tier ceiling or would leave fewer seats than people on the account.

json
{ "purchased_seats": 2 }

POST /v1/billing/portal

Open the Stripe customer portal for invoices and payment methods.

json
{ "url": "https://billing.stripe.com/p/session/..." }

GET /v1/billing/usage

Returns the current tier, billing-period dates, and usage counts for passports, agents, drop-offs, skill invocations, and published skills.

Tier limits

Monthly caps. Requests past the cap fall through to overage pricing (wallet-billed) or throw TIER_LIMIT_EXCEEDED for count-based resources.

text
                         free     developer   pro       business   enterprise
metered actions / mo     25k      250k        1.5M      10M        unlimited
seats, owner included    2        3           5         25         ∞
seat ceiling             2        5           10        ∞          ∞
audit retention          7d       30d         12mo      24mo       12mo
L3 classifications / mo  0        2k          10k       25k        unlimited
SMS / mo                 0        10          50        250        unlimited
email / mo               100      1k          5k        10k        unlimited
agents                   ∞        ∞           ∞         ∞          ∞
services                 ∞        ∞           ∞         ∞          ∞
published skills         ∞        ∞           ∞         ∞          ∞
webhook endpoints        ∞        ∞           ∞         ∞          ∞

Overage pricing (wallet-billed)

Customer-key LLM gateway calls create two bills. Your LLM provider bills the model cost directly. On self-serve plans, STACK bills a 15% gateway fee from the STACK wallet; Enterprise pricing is negotiated separately. The provider-cost figure in STACK covers only calls routed through STACK, not every call made with that provider key.

  • metered action - $0.0001 each over the monthly allowance ($1 per 10,000)
  • L3 LLM injection classification - model cost + 15% beyond the included amount
  • notification SMS - carrier cost + 15% beyond the included amount; SMS fails closed at the cap
  • notification email - send cost + 15% beyond the included amount

Paid-skill invocations are always wallet-billed at the publisher's list price, regardless of tier. Sealed-execution compute and identity verifications are wallet-billed at the upstream cost plus a 15% markup.

Errors

  • INSUFFICIENT_CREDITS (402) - wallet empty on a debit path; caller should prompt a top-up
  • TIER_LIMIT_EXCEEDED (403) - a finite seat or resource limit was reached; upgrade or reduce use
  • CONFLICT (409) - duplicate subscription change request in flight

Enterprise tier is negotiated and may include custom per-transaction pricing and commission rates. The values above are the default starting point; contact sales for custom arrangements.

stack | Docs