Billing API
Query usage, credit balance, and manage subscriptions programmatically.
Billing API
The Billing API provides access to credit balances, usage analytics, and subscription management. Billing data is scoped to organizations. The implementation is in the @broomva/billing package.
Get credit balance
GET /api/usage?orgId={orgId} -- Get the current credit balance and usage summary for an organization.
Requires: usage.read permission (any role).
Response
{
"orgId": "org_abc123",
"plan": "pro",
"credits": {
"allocated": 5000,
"consumed": 1247,
"remaining": 3753,
"usagePercent": 25,
"projectedDaysRemaining": 22
},
"period": {
"start": "2026-03-01T00:00:00Z",
"end": "2026-03-31T00:00:00Z"
}
}| Field | Type | Description |
|---|---|---|
credits.allocated | number | Monthly credit budget (1 credit = 1 cent USD) |
credits.consumed | number | Credits used this billing period |
credits.remaining | number | Credits available |
credits.usagePercent | number | Percentage of allocation consumed |
credits.projectedDaysRemaining | number | Estimated days until exhaustion (based on daily burn rate) |
Get usage breakdown
GET /api/usage?orgId={orgId}&breakdown=model -- Get usage breakdown by model, member, or time period.
Query parameters
| Parameter | Type | Description |
|---|---|---|
orgId | string | Organization ID |
breakdown | string | Dimension: model, member, or daily |
from | string | Start date (ISO 8601) |
to | string | End date (ISO 8601) |
Response (breakdown=model)
{
"breakdown": [
{
"model": "claude-sonnet-4-20250514",
"provider": "anthropic",
"requests": 142,
"inputTokens": 284000,
"outputTokens": 98000,
"creditsConsumed": 876
},
{
"model": "gpt-4o-mini",
"provider": "openai",
"requests": 89,
"inputTokens": 156000,
"outputTokens": 45000,
"creditsConsumed": 201
}
]
}Response (breakdown=member)
{
"breakdown": [
{
"userId": "user_abc",
"name": "Jane Doe",
"requests": 95,
"creditsConsumed": 612
},
{
"userId": "user_def",
"name": "John Smith",
"requests": 136,
"creditsConsumed": 465
}
]
}Response (breakdown=daily)
{
"breakdown": [
{
"date": "2026-03-20",
"requests": 47,
"creditsConsumed": 312
},
{
"date": "2026-03-21",
"requests": 52,
"creditsConsumed": 287
}
]
}Get current plan
GET /api/tier?orgId={orgId} -- Get the current plan tier and its definition for an organization.
Requires: billing.read permission (admin or owner).
Response
{
"tier": "pro",
"name": "Pro",
"creditsMonthly": 5000,
"priceMonthly": 2900,
"overagePolicy": "soft_limit"
}The priceMonthly field is in cents (2900 = $29.00). The overagePolicy is one of:
| Policy | Description |
|---|---|
hard_limit | Requests blocked when credits reach 0 |
soft_limit | Requests allowed up to 120% with warnings, then blocked |
warn | Warnings shown but requests rarely blocked |
Check overage status
POST /api/tier -- Check whether a requested operation would trigger an overage.
Request body
{
"orgId": "org_abc123",
"requestedCost": 15
}Response
{
"inOverage": false,
"overageAmount": 0,
"policy": "soft_limit",
"blocked": false,
"message": "Within budget."
}When blocked is true, the operation should not proceed. The message field contains a user-facing explanation suitable for display in the UI.
The chat endpoint calls the overage check internally before each model invocation. You only need to call this endpoint directly if you are building a custom client that needs to pre-check credit availability.
Create Stripe checkout session
POST /api/stripe/checkout -- Create a Stripe Checkout session for upgrading to a paid plan.
Requires: billing.update permission (owner only).
Request body
{
"orgId": "org_abc123",
"plan": "pro"
}Response
{
"url": "https://checkout.stripe.com/c/pay/cs_..."
}Redirect the user to the returned URL to complete payment. After successful payment, Stripe sends a webhook to POST /api/stripe which activates the plan.
Access Stripe billing portal
POST /api/stripe/portal -- Create a Stripe billing portal session for managing payment methods and viewing invoices.
Requires: billing.update permission (owner only).
Request body
{
"orgId": "org_abc123"
}Response
{
"url": "https://billing.stripe.com/p/session/..."
}The billing portal allows the user to update payment methods, download invoices, and cancel subscriptions directly through Stripe's hosted UI.
Stripe webhook
POST /api/stripe -- Stripe webhook endpoint for subscription lifecycle events.
This endpoint is called by Stripe, not by your application. It validates the Stripe signature and processes events idempotently:
| Webhook event | Platform action |
|---|---|
customer.subscription.created | Activate paid plan, set credit allocation |
customer.subscription.updated | Reflect plan changes (tier, credits) |
customer.subscription.deleted | Downgrade to free tier |
invoice.payment_succeeded | Confirm payment |
invoice.payment_failed | Send notification to organization owner |
Error responses
| Status | Code | Description |
|---|---|---|
| 401 | unauthorized | Missing or invalid token |
| 403 | forbidden | User lacks billing.read or billing.update permission |
| 404 | not_found | Organization not found |
| 402 | credits_exhausted | Operation blocked by overage policy |