Billing & plans¶
Dezycro is sold per-seat with a monthly AI token allowance that scales with your seat count. All paid tiers ship with the full product surface — what differs is the price model, seat structure, monthly token budget, and a few high-touch features (SSO, audit logs).
Plans¶
| Free | Pro | Team | Enterprise | |
|---|---|---|---|---|
| Price | $0 / month | $20 / month (1 billable user) | $39 / user / month (min 3) | Custom (target $150–300 / user) |
| AI tokens / billable user / month | 2M | 15M | 40M | Unlimited or BYOK |
| Daily token cap | 200K | — | — | — |
| Workspaces | 1 | 5 | Unlimited | Unlimited |
| Projects per workspace | 1 | Unlimited | Unlimited | Unlimited |
| Features per project | 3 | Unlimited | Unlimited | Unlimited |
| Notebooks per workspace | 2 | 3 | Unlimited | Unlimited |
| Pages per notebook | 1 (max 5,000 chars) | 100 | Unlimited | Unlimited |
| Notebook directories | — | ✓ | ✓ | ✓ |
| Billable users | 1 | 1 (Owner only) | Unlimited, subject to cap | Unlimited, subject to cap |
| Viewers | Unlimited, free | Unlimited, free | Unlimited, free | Unlimited, free |
| SSO | — | — | — | ✓ |
| BYOK (your own LLM keys) | — | ✓ | ✓ | ✓ |
| Audit log | — | — | ✓ (90-day retention) | ✓ (1-year or custom retention) |
Public pricing: dezycro.ai/pricing.
Tokens reset monthly. Your tenant's monthly budget is paidSeats × monthlyTokensPerSeat — e.g. a Team plan with 4 seats has a 160M token allowance pooled across the tenant. The 200K daily cap is a Free-tier anti-abuse measure only.
Roles, seats, and what counts¶
Dezycro has two role hierarchies and one billing concept that ties them together.
Tenant role¶
Organization-wide — applies across every workspace.
| Tenant role | Billable? | What they can do |
|---|---|---|
| Owner | ✓ | Everything, including billing & cap management |
| Admin | ✓ | Everything except billing |
| Member | ✓ | Create + edit content in any workspace they belong to |
| Viewer | ✕ | Read-only across the tenant. Does not consume a seat. |
Workspace role¶
Per-workspace — Admin / Editor / Viewer. Workspace roles are a finer-grained permission set inside a single workspace; they don't affect billing on their own.
A user with tenant role Viewer is constrained to workspace role Viewer in every workspace — you can't promote them to workspace Editor without first promoting them to tenant Member.
Billable user¶
A user whose stored tenant role is Owner, Admin, or Member. Stored — not effective. (See Pro role facade for why that distinction matters.) Viewers are not billable.
Your Stripe subscription quantity is kept in sync with the billable count automatically (see Auto-seat below) — there is no manual "add seat" / "remove seat" flow.
Pro role facade¶
The Pro plan supports one billable user — the Owner — but doesn't force you to delete or demote other members. Free works the same way. The way this works at runtime:
- Stored roles are never mutated by plan changes. When you upgrade Team → Pro, every existing member keeps their stored
Member/Admin/ workspace role in the database. - At request time, when the tenant is on Free or Pro, every non-Owner user is treated as
Viewer— both tenant role and workspace role — regardless of what's stored. The transformation runs at the central auth layer (every service sees the same view) and on the user's/meendpoint (so the UI shows what they can actually do).
This makes Pro fully reversible:
- Upgrade Team → Pro → other members go view-only, no data lost.
- Downgrade Pro → Team → every member's stored role becomes their effective role again, instantly. No migration step.
On the billing page, Pro tenants with more than 1 stored billable user see:
"N members are stored as Member/Admin but are view-only on Pro. Upgrade to Team to restore their roles."
Auto-seat (Team only)¶
Pro is a flat plan: quantity is always 1, regardless of how many users exist. Auto-seat applies to Team:
- Adding a billable user (invite a new Member, or promote a Viewer to Member/Admin):
- If
billableUserCount > 3→ Stripe quantity goes up by 1. Nothing is charged at that moment and no invoice is raised. Instead, your next renewal invoice carries an extra prorated line for the new seat, covering exactly the days that were left in your current billing period (your subscription's own period, not the calendar month). The line is priced at what you actually pay, so a percent-off discount applies to it too. - If
billableUserCount ≤ 3→ no Stripe change. You're already paying the 3-seat floor.
- If
- Removing a billable user (delete, or demote to Viewer):
- If
billableUserCount (after) ≥ 3→ Stripe quantity goes down by 1. There is no mid-period credit or refund; the lower seat count is billed from your next renewal. - If
billableUserCount (after) < 3→ no Stripe change. Quantity stays at the 3-seat floor.
- If
- Re-filling a seat in the same period — you remove a billable user, then add one before the period ends — is not charged again: you already paid for that seat this period.
In short: Team always pays for at least 3 seats. Below that, you have paid-for headroom you can use any time without changing your bill. Seat changes made during a free trial bill nothing; the first invoice after the trial bills the seats you have then.
Stripe quantity sync is atomic per-tenant, so rapid invites are coalesced into a single Stripe call and concurrent role changes can't race past the cap.
Billable-user cap (Team & Enterprise)¶
To protect against an over-eager admin doubling your monthly bill, the Owner can set a maxBillableUsers cap — a hard upper bound on the billable user count. Independent of Stripe quantity: the cap controls consumption, not payment.
- Owner-only. Only users with
BILLING_MANAGEpermission can set or change it — by default, just the tenant Owner. - Applies on Team and Enterprise only. Setting a cap on Free or Pro returns
CAP_NOT_SUPPORTED(Pro is structurally capped at 1 by the facade; Free is single-user). - Lower bound =
max(currentBillableUserCount, tier.seatFloor). We never auto-demote — you can't shrink the cap below what's already used. (CAP_BELOW_USAGEif you try.) - Upper bound = none. Set to
nullfor unlimited. - Stripe quantity is unaffected by cap changes.
What happens when the cap is reached?
| Path | Behavior |
|---|---|
Admin invite / role promotion (POST /api/manage/users, PUT /api/manage/users/{id}/role) |
Hard block — HTTP 400 BILLABLE_CAP_REACHED. Admin must re-invite with Viewer role. |
| User self-join (OAuth callback, invitation acceptance, domain auto-join) | Soft fallback — user is shown a dialog explaining the cap is reached and offered to join as a Viewer instead. Requires explicit consent. |
Cap state is updated atomically per tenant, so concurrent self-joins can't squeeze past it.
Setting the cap¶
Organization settings → Billing → Billable-User Cap.
UI shows current cap (or "Unlimited") with a hint like "You're using N of M cap". Admins (non-owner) see the value but can't edit. Members and Viewers don't see this section.
Upgrade & downgrade¶
Free → Pro¶
Billing page shows: "$20/mo for 1 billable user. Unlimited free Viewers." If you already have more than 1 billable user, you also see a warning that the others will become view-only via the Pro facade until you upgrade to Team.
Free / Pro → Team¶
Billing page shows a per-seat cost preview computed at checkout:
billableUserCount ≥ 3→ "You have N billable members. Starts at N × $39/seat/mo = $(N × 39)/mo."billableUserCount < 3→ "Team requires a minimum of 3 seats. You have N billable members. Starts at 3 × $39 = $117/mo. You can invite up to (3 − N) more members without increasing your bill."
You must acknowledge the line item before checkout.
Discount codes at checkout¶
If Dezycro has given you a discount code, enter it in the Add promotion code field on the Stripe Checkout page when you upgrade. Stripe checks the code and shows the discounted amount before you pay. See Discounts & credit for how the discount then shows on your Billing page.
- A code works once for your organization. Codes come from Dezycro offers, so the same code may be shared with other organizations, but yours can use it once, even if you cancel and subscribe again. An offer can also end, after which its code stops working. A code that's expired, no longer available, or already used by you is rejected by Stripe with its own message. For a code you've already used, Stripe only says "This code is invalid."
- Already subscribed? There's no checkout for you to type a code into, and the Stripe portal has no code field. Contact support@dezycro.ai and we'll apply the discount to your existing subscription. It takes effect from your next invoice.
- One checkout at a time. A checkout page stops working 35 minutes after it was opened, and starting a new upgrade closes any earlier checkout that is still open. If a checkout expires or you abandon it, your code isn't used up. Start the upgrade again from the Billing page.
- Checkout may show prices in your local currency, but your invoice and the Billing page show USD.
A trial code is different. You redeem it on Dezycro's Billing page, not in Stripe Checkout. See Trial codes.
Team → Pro¶
Stored roles are not touched. Other members go view-only at runtime via the facade. Stripe quantity drops to 1.
Paid → Free (cancellation, payment failure)¶
- Tenant tier flips to FREE; subscription stops.
- Free's limits apply: 1 workspace, 1 project per workspace, 3 features per project, 1 billable user (the Owner), 2M tokens / mo, 200K daily cap.
- Existing resources above those limits are preserved but read-only. Other members keep their stored roles but are view-only until you upgrade (see Pro role facade). You can't create more resources or invite billable users until you upgrade. You can still invite Viewers, which are free on every plan.
- Any
maxBillableUserscap is cleared (it doesn't apply on Free). - The admin sees a warning summarizing what's now past the limit and prompting an upgrade.
When a payment fails, the Billing page and Organization settings → Billing show "Your last payment didn't go through…" with an Update payment method button that opens the Stripe portal. Your organization is on the Free plan until the payment goes through. Stripe keeps retrying the payment, and your plan comes back once it's paid. While the payment is past due, you can't redeem a trial code or start a checkout for another plan: update the payment method first.
Stripe portal¶
On the Billing page, Manage Payment Method and Cancel Subscription open the Stripe customer portal: update your payment method, download invoices, change plan (upgrades prorate immediately; downgrades apply at next renewal), or cancel.
These buttons are gated by BILLING_MANAGE permission — Owner-only by default.
Trial codes¶
A trial code gives your organization a plan for free until a fixed date, for example "Team free until December 31". Codes come from Dezycro offers, so the same code may be shared with other organizations; yours can redeem it once. No payment method is needed.
Redeeming a code¶
Only the Owner can redeem. Open the Billing page (account menu → Upgrade plan, or Organization settings → Billing → Change Plan).
- Type the code into Have a trial code? and click Check code. Upper or lower case both work, and spaces and dashes are ignored.
- Before anything is used, the page shows what the code gives you: "This code gives you Team until December 31, 2026, 00:00 UTC." If the code replaces a trial you already have, it says which trial and when that one ends.
- Click Redeem to apply it, or Cancel to leave the code unused.
The end date belongs to the offer, not to when you redeem. Everyone who redeems the same code stops on the same date. A code redeemed the day before its end date gives you one day. That's why the page shows the exact end before you confirm. Dates are shown in UTC, and access ends as that date begins (00:00 UTC).
During the trial¶
- The Billing page says "You're on the Team free trial", shows how long is left, and gives the exact end date. Organization settings → Billing shows the plan as "Trial — not billed".
- There's no Stripe subscription behind a code trial, so there's nothing to manage in the Stripe portal yet.
- You can add billable users at no charge. Your own billable-user cap still applies.
- To keep the plan, subscribe any time with Subscribe to keep Team (or the plan you're on). The trial ends as soon as you're paying, your organization can't redeem the same code again, and your subscription is billed for every billable user you have then.
When the trial ends¶
If you haven't subscribed, your organization returns to the plan it had before the trial, shortly after 00:00 UTC on the end date. If that plan is Free (or Pro), everyone except the Owner becomes view-only until you upgrade. Their stored roles are kept (see Pro role facade).
When a code can't be used¶
The page names the reason. When the refusal is about your current plan or trial, the code is not used up. You can keep it and use it later.
| What you see | Why |
|---|---|
| "You're on a trial that ends on …. Use this code after that trial ends" | You're on a free trial you started yourself, or on a Pro or Team trial from Dezycro that runs through Stripe. Redeem the code after that trial ends. |
| "Your organization already has a paid subscription, so a trial code can't be applied" | You're already paying. A discount is the right tool for you: contact us. |
| "This code would end your current trial early" | You're on another code's trial (or an Enterprise trial from Dezycro) that runs later than this code's end date. A code never shortens a trial you already have. |
| "This code gives a lower plan than your current … trial" | Your current trial is on a higher plan. A code never lowers your plan. Use it once that trial ends. |
| "This code gives a lower plan than your current … plan" | Your organization already has a higher plan that isn't billed through Stripe, such as an invoiced Enterprise plan. Contact support. |
| "Your billing subscription needs attention" | Something on your Stripe subscription needs fixing first. Contact support. |
| "Your organization has already used this code", "This offer ended on …", "This offer is no longer available", "We couldn't find that code" | The code itself can't be redeemed: you've used it already, the offer has ended or been withdrawn, or the code is mistyped. |
| "Billing is busy right now", "Your billing changed while we were applying the code" | Something else changed your billing at the same moment. Nothing was used, so try again. |
If you're on another code's trial (or an Enterprise trial from Dezycro) and the new code runs at least as long on at least the same plan, it replaces the current trial. When the new trial ends, you return to the plan you had before either trial, never to the replaced trial's plan.
Using a trial earlier doesn't stop you redeeming a code: the offer was shared with you on purpose.
Discounts & credit¶
When your organization has a discount or credit, the Billing page and Organization settings → Billing show a Discounts & credit section. When there's neither, the section isn't shown at all.
Discounts¶
Each discount is listed with its name, what it takes off, and when it applies, exactly as it applies to your subscription. If you have more than one, all of them are listed, and the Billing page always shows their current effect on your bills. A discount you entered as a code at checkout and one Dezycro applied to your subscription look the same.
During a Stripe trial, the Billing page shows when each discount starts applying. A discount that will never apply to a charge is not shown.
A discount set up directly in Stripe that this view can't describe appears as "A discount set directly in Stripe also applies to your invoices — your Stripe invoice shows it."
Credit¶
Dezycro can give your organization credit: a fixed amount that your invoices use up before your card is charged. The section shows "Credit remaining: $351.00", read live from Stripe, with a line on how it's used:
- With no discount, it also shows your current monthly bill, for example "Your current bill is $117.00/mo — an estimate, because it changes with your seat count", so you can judge roughly how long the credit lasts. More seats use it up faster.
- With a discount, credit is applied to each invoice's total after the discount.
- During a Stripe trial, credit starts to be used from your first charge.
- Without a subscription, credit waits: it's applied to your invoices once you subscribe.
If the credit is more than an invoice, the rest carries forward: nothing is charged that period, and there is no refund. Credit is never paid out. If you cancel, it stays on your account and applies again if you subscribe later. Credit never changes your plan.
Prices on your plan card¶
The plan card and seat total show the price before any discount or credit. When a discount or credit applies, they say so ("List price — your discounts and credit are shown above.", "$117/mo total before discounts and credit"). Your Stripe invoice has the exact amount. If Stripe can't be reached, the section says it couldn't load your discounts and credit, and the prices are marked as list price. Your plan and seats are not affected.
What counts toward your AI token allowance¶
Your monthly budget is paidSeats × monthlyTokensPerSeat, pooled across the tenant — anyone in the tenant draws from the same bucket.
| Operation | Typical tokens / call |
|---|---|
| Test case generation (from TRD) | 20,000–50,000 |
| AI chat messages (PRD editing) | 1,000–5,000 |
| AI autocomplete (in-editor) | 500–2,000 |
/<prefix>:dz-author PRD/TRD authoring |
5,000–30,000 |
| Workbook sweeps (Companion) | 2,000–8,000 |
What does NOT count¶
- Document upload + ingestion (embeddings run on shared infra)
- Vector search retrievals
- Reading the workbook, listing features, navigating the UI
- Verifier binary execution (runs locally; no LLM)
Hitting the cap¶
- The in-flight LLM call is allowed to complete.
- Subsequent LLM-gated actions return: "Monthly AI token allowance exhausted. Upgrade to continue."
- Non-LLM features (workbook editing, test runs, verifier, document upload, navigation) keep working.
Upgrade or add seats at any time from the Stripe portal — the new allowance applies immediately.
Subscription status API¶
For programmatic access, GET /api/billing/subscription-status returns:
| Field | Meaning |
|---|---|
tier |
FREE / PRO / TEAM / ENTERPRISE |
paidSeats |
Stripe quantity (Pro=1, Team=max(billableMembers, 3), Free=0) |
billableMembers |
Stored Owner + Admin + Member count |
viewerCount |
Stored Viewer count |
pricePerSeatCents |
Your subscription's own Stripe price per seat, else the tier list price: 2000 (Pro), 3900 (Team), custom (Ent), null (Free). Never includes discounts or credit |
pricePerSeatSource |
STRIPE_PRICE (your subscription's price) or TIER_LIST_PRICE (Dezycro's list price, used when your own price isn't available) |
seatFloor |
1 (Pro), 3 (Team), null (Free) |
monthlyTokensPerSeat |
2_000_000 / 15_000_000 / 40_000_000 / null (Ent BYOK) |
dailyTokenCap |
200_000 (Free), null otherwise |
maxBillableUsers |
The Owner-set cap, or null if uncapped |
currentPeriodEnd |
Renewal date as Unix epoch seconds |
trialEndsAt |
When the current trial ends (ISO-8601 instant), or null when there's no trial |
trialKind |
STRIPE (a trial on a Stripe subscription, converts with a card on file), MANUAL (a trial code or a trial from Dezycro with no subscription, ends on its date), or null when there's no trial |
discountsAndCredit |
Your discounts and remaining credit, read live from Stripe: availability (AVAILABLE / UNAVAILABLE), currency, discounts[] (name, percentOff or amountOffMinor, duration for how long it applies to your subscription, state for where the discount stands on your subscription, and the dates for that state), credit (amountMinor, currency), otherStripeDiscount |
paymentPastDue |
true when your last payment failed and hasn't been paid yet |
Audit trail¶
Every billing-affecting action lands in the audit log:
| Action | When it fires | Key metadata |
|---|---|---|
SEAT_ADDED |
Billable user created or promoted into a billable role | user, trigger (user_created / role_promoted) |
SEAT_REMOVED |
Billable user deleted or demoted to Viewer | user, trigger (user_deleted / role_demoted) |
PLAN_UPGRADED |
Your plan goes up, for any reason: a checkout or plan switch, a failed payment that's paid, a trial starting, or a trial code redeemed | fromTier, toTier, cause |
PLAN_DOWNGRADED |
Your plan goes down, for any reason: a plan switch, a failed payment, a subscription ending, or a trial (including a code trial) ending | fromTier, toTier, cause |
TRIAL_CODE_REDEEMED |
The Owner redeems a trial code | tier, trialEndsAt, and, when it replaced a trial, replacedTier / replacedTrialEndsAt |
BILLING_CAP_CHANGED |
Owner edits maxBillableUsers |
oldCap, newCap, current billable count, paidSeats |
One row per real plan change. A change that leaves your plan where it was writes no row. cause says what changed it: subscription_changed, payment_failed, subscription_ended, trial_started, trial_ended or trial_code_redeemed.
Who is shown as the actor: when you caused the change, by starting a trial or redeeming a trial code, the row names you. When Stripe or Dezycro caused it (a checkout or plan switch coming back from Stripe, a failed or recovered payment, a subscription ending, a trial running out), the actor is shown as System, with no email.
BYOK (Pro and above)¶
Tenants on Pro, Team, or Enterprise can avoid Dezycro's token meter entirely by configuring BYOK — all AI calls go to your own provider account and are billed there. Your Dezycro invoice becomes just the seat fee.
Enterprise contracts are set up by sales: Stripe subscription quantity and price are negotiated upfront. Auto-seat still runs (role changes adjust quantity within the negotiated bounds), but pricing is not enforced by the application.
Contact sales for Enterprise pricing.