Billing, credits, and seats
Project88's billing model — per-user credits, per-org seats, real-time deduction on LLM usage, and governance for org owners.
Project88 has a user-centric billing model: every user has their own credit balance and personal plan, and orgs can issue seats that grant members access to a higher tier without each member paying.
The model
| Concept | Where it lives |
|---|---|
| Personal plan | user_billing.tier (per-user) |
| Personal credits | user_billing.credits_balance (per-user) |
| Org seat | org_seats.assigned_tier (per-user-per-org) |
| Effective tier | org_seat?.assigned_tier ?? user_billing.tier |
A user's effective tier is whatever's bigger — their personal plan or the seat their current org assigns them. Switching orgs effectively switches plans, with no extra steps from the user.
Credits and deduction
Credits are per-user, not per-org. Every LLM completion deducts from the user that initiated it.
The flow:
- The browser starts a chat completion via the
chat-proxyEdge Function. - The proxy streams the response back, including a final
usageevent. hosted.js(src/services/backends/hosted.js) catches the usage event and callslogUsage(), inserting a row intousage_logsand triggering credit deduction.- Supabase emits a real-time update on
user_billingvia a Postgres channel. - The browser's billing store (
src/store/billing.jsx) subscribes to the channel and updates the balance in memory. - The
CreditsDisplaypill in the top bar animates digit-by-digit to the new balance.
The whole loop is sub-second — you see credits tick down as the response finishes streaming.
usage_logs schema
From migration 002_managed_tables.sql:
id,org_idprovider,modelprompt_tokens,completion_tokenscreated_at
Totals are derived by summing the two token columns at read time. The
/status/* pages and any future usage dashboards read from this table.
Org seats and governance
Owners and admins control governance from Settings → Members
(OrgMembersPanel.jsx) via three RPCs:
update_org_member_role— promote / demote between owner, admin, memberremove_org_member— kick a member out of the orgtransfer_org_ownership— hand ownership to another member
When a member is added, an org_seats row is created with the org's
assigned tier. Removing a member soft-deletes the seat; their
personal plan is unaffected.
Plans
| Plan | Notes |
|---|---|
free | Default. Cap on monthly credits. |
pro | Higher cap; richer tools and limits. |
enterprise | Custom — talk to us. |
Plans are gated by effectiveTier, so any user with a seat on a pro
org has pro capabilities regardless of their personal plan.
What you pay for
- Credits consumed on LLM calls — based on the model and token count. Project88 marks up a small percentage on top of the provider's wholesale rate to fund the platform.
- Project88 plan — flat monthly subscription that includes a credit allowance. Pro plans get more credits per month.
- Telnyx SMS — per-message rates billed directly to your Telnyx account.
- Composio toolkits — Composio's own pricing applies for some toolkits.
Status pages
src/pages/status/ houses PaymentRequired, BillingSuccess, and
related pages used during the upgrade and recovery flows. They're
intentionally stand-alone routes that bypass the canvas shell so they
work even when an org is over its limit.