Billing & quotas
For agents:
get_usage(org="acme")(exact daily accepted events, plan, overage flag, credit balance),get_billing_plans(org="acme")(catalog + whether checkout is configured),set_overage(org="acme", enabled=true)(org:admin, audited). Upgrades happen in the dashboard — there is no checkout tool.
One meter
1 error = 1 event, 1 transaction = 1 event. Spans, sessions, breadcrumbs, and client reports are free. There is no per-seat pricing for viewers.
| Plan | Price / month | Events included | Retention | Billable members | Overage (per 100k events) |
|---|---|---|---|---|---|
| Free | $0 | 100,000 | 30 days | 3 (5 projects) | not available |
| Starter | $29 | 1,000,000 | 90 days | 15 | $5.00 |
| Team | $79 | 5,000,000 | 90 days | 40 | $5.00 |
| Business | $249 | 20,000,000 | 90 days | 100 | $3.00 |
| Scale | $499 | 50,000,000 | 90 days | 250 | $2.00 |
Paid plans have unlimited projects. Viewers are unlimited everywhere.
Exact metering
Accepted events are counted by a per-organization Durable Object (OrgQuota) and flushed to the control database as usage_daily rows by category — this is the number on the usage page and the invoice. The sampled analytics index is never used for billing. Filtered events, SDK-side drops (client reports), and rate-limited events are recorded as outcomes for transparency but are not billed.
GET /v1/orgs/{org}/usage returns the plan, overageEnabled, daily[] (date, category, accepted) for the last 31 days, and credits (balance, entries with expiry, last invoice application, and appliesToInvoices / notAppliedReason: whether anything can deduct them).
Hard cap versus overage
- Default: hard cap. When the period's accepted events reach the plan allowance plus a 10% grace, the quota object writes a flag that ingest reads; further envelopes get
429withX-Sentry-Rate-LimitsandRetry-After, and SDKs back off. Nothing is billed beyond the plan. - Overage opt-in (
POST /v1/orgs/{org}/billing/overage {"enabled": true},org:admin): the flag is never written; events above the allowance are billed at the plan's overage rate. Free has no overage. - Counters reset on the organization's billing anchor day (nightly job).
Credits
Credits (launch, migration, startup programs) live in a ledger and apply automatically on invoice creation:
- Cover at most 50% of any invoice, across all credits combined; individual credits may carry a lower per-credit percentage.
- Never apply to tax — only the pre-tax subtotal.
- Active balance is capped at $1,000 per organization; grants clamp to the room left.
- Drawn FIFO by nearest expiry. The balance and expiry dates are visible in
get_usageand on the usage page.
Promotional credits are applied by discounting the invoice before it is finalized, which only works for Stripe-billed organizations. Polar issues its own invoices as the seller of record, so credits granted to a Polar-billed organization cannot come off its bill. The balance says so rather than reading as money: credits.appliesToInvoices is false with a notAppliedReason in GET …/usage and get_usage, and Settings → Billing labels it "not applied" and gives the reason. With no credits granted and none that could apply, the Credits panel is not shown at all. An organization not yet billed is judged by the provider it would be billed by. Tell us if you are holding a credit that does not apply. Fix-agent credit packs, which are purchases rather than discounts, work on both providers.
Checkout and portal
Who you are buying from
Bugwatch supports more than one payment provider, and which one bills you changes who the seller is — so it is stated, not hidden:
| Provider | Seller of record | Sales tax / VAT | Invoices and refunds come from |
|---|---|---|---|
| Polar (default) | Polar | Handled by Polar, worldwide | Polar |
| Stripe | Bugwatch | Charged by Bugwatch where we are registered | Bugwatch |
GET /v1/orgs/{org}/billing/plans reports the active one under provider (id, name, merchantOfRecord), and Settings → Billing shows it above the plan ladder. Your organization is assigned a provider the first time it pays and stays on it: if the default changes later, your existing subscription, portal, and invoices do not move.
The endpoints
GET /v1/orgs/{org}/billing/plans returns every plan with purchasable set when a provider is configured and a product exists for it. Upgrading is POST /v1/orgs/{org}/billing/checkout {"plan": "team", "returnPath": "/o/acme/settings"} → {"url", "provider"} (a redirect to the provider's hosted checkout); managing cards, invoices, and cancellation is POST …/billing/portal → {"url", "provider"}. Both require org:admin, return 501 when no provider is configured, and are deliberately not exposed as MCP tools — purchases stay human-initiated. Plan changes come back through the provider's webhooks and update the allowance immediately.
Cancelling leaves the plan in place until the period you have paid for runs out; the drop to Free happens at expiry, not at the moment you cancel.
What agents can do here
| Action | Tool | Scope |
|---|---|---|
| Read usage, plan, credits | get_usage |
org:read |
| Read the catalog | get_billing_plans |
org:read |
| Turn overage on/off | set_overage |
org:admin (audited) |
| Upgrade, change card, cancel | none — dashboard | — |
What the plan enforces
- Project cap. The Free plan includes 5 projects. Creating a sixth returns
402with{"error": "project limit reached …", "limit": 5, "plan": "free"}fromPOST /v1/orgs/{org}/projectsand from thecreate_projecttool. Paid plans are unlimited. - Retention follows the plan. New projects are created in the plan's tier (30 days on Free, 90 days on every paid plan). When a plan changes — Checkout, a subscription update, or a downgrade to Free — every project in the organization moves to the new tier within seconds, for events received from then on. Events already stored keep the retention they were written with; nothing is deleted early on a downgrade, and nothing is extended retroactively on an upgrade.
- Period resets. Exact usage counters reset on your billing anchor day (the 1st unless your subscription anchored elsewhere; 29–31 clamp to the last day of shorter months). Resets are idempotent per period, so a delayed nightly run never double-resets or skips a month.
How overage is billed
With metered overage on, the nightly job computes each day's overage events — the part of that day's accepted errors and transactions that pushed the period's cumulative total past the allowance — from the exact per-day counts, and reports it to whichever provider bills your organization — a Stripe billing meter event, or a Polar usage event — under the identifier org:date. Each org-day is reported once; the last seven days are re-checked every night, so a missed run catches up and a retried run never double-bills. Days with no overage are recorded with zero and no call to the provider. So are days your organization was not billable for overage at all — overage off, or a plan without it — because each day's decision is taken once, the night after it happens, and never revisited: switching overage on does not bill the week before you switched it on, switching it off does not erase days you had already agreed to, and changing plan mid-period does not re-price days already recorded against your old allowance. Settings → Billing shows the events reported so far this period and the last reported day; the same numbers come back from get_usage under overage.