Plans and subscriptions

Updated Oct 16, 2026 Open the tool

Zoov.dev sells one global subscription per user that unlocks a tier (Plugin Pass, Standard, Pro or Max) across every game workspace, plus optional monthly credit plans that add credits without changing the tier. All plans are billed through Stripe and managed from /api/v2/billing/portal?return=/app.

The tiers and what they include

Zoov.dev has a free tier and four paid tiers. Prices are in USD. Every paid tier can be billed monthly or yearly.

Free. Sign in with Discord and get 50 credits, yours to spend on any AI tool. Every tool with a daily allowance (since 2026-09-27; the workspace asks for the sign-in before any tool is touched): 5 conversions or optimizations a day (15 before), 1 UV map, 1 vehicle in the Vehicle tool, 1 ped exported by the Peds tool (since 2026-09-28) and 1 mod built into a resource a day (DAY_LIMITS in config/plans.ts; the Free card reads "1 UV map, 1 vehicle, 1 ped, 1 shell, 1 mod a day"), the Siren tool's 3D preview on Standard and up, the Vehicle tool's Bring a vehicle (lights and extras from one's own police vehicle, since 2026-09-30) on Standard and up while Free keeps the catalogue's lights, community support on Discord. In the workspace Designer (since 2026-09-23): 20 minutes of editing a day (30 until 2026-09-27), exports up to 1024 pixels, 3 YTD or DDS exports a day, the live 3D preview for 3 models a day, and 3 saved designs. Standard's card says "Unlimited Designer time, 3D preview and saved designs" and "Full-size exports, unlimited YTD and DDS" (it used to say "Save projects, no daily editor limit", which the workspace did not enforce). The rules are DESIGNER_LIMITS in config/plans.ts; the workspace guide's "Daily limits and plans" describes what a person sees. Clothing packs (PACK_LIMITS, 2026-09-24): the free plans keep one pack, on the device only; Standard keeps 3, Pro 10 and Max 50 (three each until 2026-09-25, raised so the plans differ in more than sharing and history), and each can be saved to the cloud (other devices, versions; a choice per pack, Save to cloud) where its files count against workspace storage; the free plans build up to 10 items a pack, 5 per slot and ped and 7 variations an item, as Durty Cloth Tool's free tier does, and the paid plans have no build limit; Pro shares a pack with two people and Max with anyone, and a shared pack counts against its owner only; automatic history lasts 30, 90 and 365 days. Deleting a pack is how another starts. AI names and tags for a pack's items (2026-09-25, PACK_LIMITS.aiNamesPerDay): included on the paid plans up to 2,000 items a day with no credits, not on the free plans; the owner may still choose a price instead (see packs.md, "AI names and tags"). Numbered pack builds kept (2026-09-28, PACK_LIMITS.keptBuilds): the newest 10 on Standard, 30 on Pro, 100 on Max, older unnamed ones rotating out as new ones are made; named builds stay (packs.md). The pack's other paid tools (2026-09-28, PACK_LIMITS.tools): the converter fixes the findings offer (Resize, Make mipmaps, Make LODs, Reduce triangles, Shrink, Fix all) and Make or Export pictures are Standard and up; on a free plan each opens the plans with Standard drawn out.

Plugin Pass. $8 a month, or $90 a year ($7.50 a month). The yearly Stripe price is price_1UNIOeFAb2p6qypZd9Xj0vTV (USD, since 2026-10-06); the one before it, price_1TiSoXFAb2p6qypZaYKCObJ2, had been minted in AUD by mistake (A$90, about US$60, while the dialog said $90), was never subscribed to, and is archived. A separate legacy USD yearly price at $60 (price_1T8wqHFAb2p6qypZ0k3jdFLN) still carries two subscriptions and is not sold. No monthly credits. Photoshop and Photopea plugin, live 3D preview inside the plugin, YFT, YDD and YTD imports. Only shown on the pricing page to signed-in users who hold no paid tier. That is all it buys: since 2026-09-30 (the owner's rule, "Lite and Booster are Free users; non-free is only Standard and up") a Plugin Pass holder has exactly Free's limits and prices everywhere else: the daily allowance, workspace storage, Optimize, the Designer, 1 reference picture, the image routes' request limits, the Code agent's 500-character prompt and Free's credit price on every AI tool. Before that day Lite paid one step under Free on the image rows and carried 2 reference pictures, 1,250-character Code prompts and a middle step of request limits.

Discord boosters. Boosting the Zoov.dev server gives the booster role, which since 2026-09-30 is Free in every limit and price (it had 2 GB storage, 250 MB files, 30-day retention and 10 pins, unlimited Optimize in batches of 100, an open Designer, and Lite's prices before). It does not open the plugin.

Standard. $15 a month, or $160 a year ($13 a month). 750 credits every month (500 before 2026-09-14). Model to prop conversions free, Photoshop and Photopea plugin, premium model library and custom uploads, save projects with no daily editor limit, unlimited optimizations with batches up to 100 files.

Pro. $25 a month, or $240 a year ($20 a month). 1,500 credits every month (1,000 before 2026-09-14). Everything in Standard plus game file conversions free, lowest credit prices on every AI tool, priority queue on every job, unlimited exports with 500 file batches, priority support and early access. Marked "Most popular". Since 2026-10-02 (built, not live yet): Sync pack, a pack's builds pushed to a GitHub repository folder or posted to a Discord channel after every build (PACK_LIMITS.sync, Pro and Max; packs.md). Daily limits (2026-10-03): Pro 20 GitHub syncs per pack and 10 GB sent a day, Max 100 and 50 GB; Enhanced packs sync on Max only.

Max. $149 a month, or $1,500 a year ($125 a month). 15,000 credits every month (8,000 before 2026-09-14). Everything in Pro plus highest queue priority, largest Code Agent context, upload whole resources with 2,000 file batches, API and CLI access for automation (Optimize since 2026-10-01; the Packs API, pack builds as files with webhooks, built 2026-10-02 and not live yet).

Conversions in the new workspace (2026-09-13, in progress). In /app, converting a model to a prop is free on every plan: 3 a day on Free, unlimited on Standard, Pro and Max, and a model from an AI generation converts without counting. Pro's priority queue and Max's highest queue priority apply to that conversion queue when it lands.

Other limits from the comparison table: largest optimizable file 50 MB on Free, 80 MB on Standard, 100 MB on Pro and Max; batches run 2 files at once on Standard, 3 on Pro, 5 on Max; recursive folder upload and API/CLI access are Max only (the automation API at https://zoov.dev/api/public/v1 answers other plans 403 plan_required; it optimizes files today, see API keys). Loyalty credits (up to 3,100 over two years) come with every tier from Standard up.

Monthly versus yearly billing

The pricing page defaults to monthly with a "Monthly / Yearly" toggle. Under the price it says "Billed monthly, cancel any time" or, on yearly, "{yearly total} billed once a year, {n}% less than monthly". The yearly saving is 11% on Standard, 20% on Pro, 16% on Max and 6% on Plugin Pass.

Yearly checkout goes straight to Stripe's page since 2026-10-06. The dialog used to arm the button on a first click ("Confirm $240 for 12 months", ten seconds to click again) because the year is non-refundable; in the fortnight before the change 24 people saw it, 6 went on and 13 switched back to monthly, and six yearly plans were live in all. The terms now stand over Stripe's own Pay button (custom_text.submit on the session: "One payment covers 12 months and is not refundable. Credits arrive month by month. Cancel any time to stop the next year."), joined to the replacement note when a plan is already held.

Button labels for a signed-in user depend on what they hold: "Choose {plan}" when they have no plan, "Current plan" (disabled) on the plan they already have, "Upgrade to {plan}" for a higher tier and "Switch to {plan}" for a lower one. Under "Current plan" the card says "Change billing or cancel from billing", which links to /api/v2/billing/portal?return=/app.

Yearly plans receive their credits month by month, not 12 months' worth at once. See the Credits doc.

Upgrading or changing plan

A plan change on Zoov.dev is a brand new subscription at full price, not a Stripe proration. The pricing card warns: "Replaces your {current} plan the moment it is paid. Unused {current} credits are removed, {new} credits arrive straight away. No proration." Stripe Checkout repeats it above the pay button: "This replaces your current plan the moment it is paid. The old plan ends immediately with no refund or proration, its unused monthly credits are removed, and the new plan's credits arrive straight away. Credit packages are not affected."

Once the new subscription is paid, every older main-plan subscription on the same Stripe customer is cancelled outright with no refund. Monthly credit plans and team subscriptions are never touched. The old plan's remaining temporary credits are voided, its tier role is removed, and the new plan's full monthly allowance is granted immediately. If the old and new plan are the same product (monthly to yearly), the credits are kept.

Buying the exact plan you already hold is blocked: the checkout page redirects to /pricing?error=already_on_plan. A generic checkout failure redirects to /pricing?error=subscription_failed. Successful checkout lands on /workspace?subscription=success&plan={plan}.

Cancelling and keeping access

Cancel from the Stripe billing portal. In the user menu it is called "Billing portal" and lives at /api/v2/billing/portal?return=/app (sign-in required). The portal also handles card changes and invoices.

Cancelling stops the next charge. The Terms of Service say "Your cancellation will take effect at the end of the current paid term." and the pricing FAQ says "Cancelling stops the next charge and you keep access until the end of the period you already paid for." Auto-renew is shown as "Disabled (cancels at period end)" in the subscription record until the term ends.

When the term actually ends (or when Stripe marks the subscription past_due, unpaid, incomplete_expired or paused), the plan's tier role is removed, the Early Adopter role is removed if no other main plan is active, and that plan's remaining temporary credits are voided. Permanent credits and loyalty credits stay. Ending a monthly credit plan removes only that plan's credits. There is no partial refund for cancelling early.

Roles, Early Adopter and is_pro

Access tiers on Zoov.dev are Discord roles mirrored into the user's metadata as permission_role with values lite, standard, pro, max, plus booster (server boosters) and referrer. The tier hierarchy is booster < lite < standard = referrer < pro < max. Pricing and feature locks use this role, and lock messages read "Locked to Pro+" or "{feature} requires Pro+". Since 2026-09-30 booster and lite have Free's row in every table (WORKSPACE_QUOTAS, OPTIMIZE_LIMITS, DESIGNER_LIMITS, DAY_LIMITS, REFERENCE_LIMITS in config/plans.ts, FEATURE_PRICES and EXTRA_INPUT_IMAGE_CREDITS in pricing.ts), the image routes rate-limit them as Free, and normalizeCodePromptTier counts them as Free; lite keeps only tools.photoshop (the plugin and its preview, also granted by a Plugin Pass subscription). Referrer is unchanged.

When any main plan (not a credit plan) becomes active, the webhook assigns the Stripe product's tier role and the shared Early Adopter role on Discord, and sets is_pro: true and is_standard: true in user metadata. New code checks permission_role; the two flags are legacy (verify what still reads is_standard).

Because roles are Discord roles, the user must be in the Zoov.dev Discord server for the role to land. Since 2026-10-02 a role that cannot be added or removed (most often Discord's "Unknown Member": the buyer is not in the server) is logged and passed over. The plan still activates, credits are still granted or voided, and plan-change supersede still runs. Before that, the role failure failed the whole webhook: Stripe kept resending the event, and every step after the role was skipped, including cancelling the older plan on an upgrade. Joining the server later does not add the role by itself (the bot has no plan-role sync on join); staff add it by hand. A subscriber with no Discord id on their profile still makes the webhook fail with "User {id} has no discord_id".

Monthly credit plans (Stripe product metadata credit_plan: true) deliver credits only. They assign no role and do not set is_pro, so buying one alongside Pro does not touch the Pro tier, and cancelling one does not remove it.

In the workspace (/app) and the v2 API the tier is the subscription or the role, whichever is higher (2026-09-14, src/lib/server/workspace/tier.ts): an active or trialing main-plan subscription on stripe_subscriptions is the tier it sells, read by product or price id, a team subscription is Pro, and the Discord role still counts, so a person on a paid plan who is not in the Discord server, or whose roles have not synced yet, is on their plan in the workspace the moment the webhook wrote the row. past_due is not a plan there. The legacy pages keep reading permission_role alone. Since 2026-10-06 the (app) layout load also reads billing (billingTrouble in tier.ts: a non-team subscription past_due or unpaid, unpaid winning), and the top bar draws a red Payment failed pill (shell/BillingPill.svelte, to the Stripe portal; the triangle alone on a phone) in place of Upgrade, so a late payer learns why they are drawn as Free. In the month before, 1,068 renewal charges failed (mostly insufficient funds), 104 plans sat past due and the dunning cron recovered six.

Which button sold it (2026-09-22). Workspace checkouts carry checkout_source in the Checkout session's and the subscription's (or payment's) metadata: the plans dialog's source (topbar-upgrade, credit-pill, generate-model, profile-menu...), credits-dialog for packs bought there, and discover:<from> for doors from outside the workspace (/app?plans=pro&from=plans-section; the front page's plan cards send plans-section, the plugin page plugin-page, the plugin panel plugin-panel). The payments webhook now copies the subscription's metadata into stripe_subscriptions.metadata (it stored {} before), and PostHog's payment_subscription_checkout_created and payment_checkout_created carry it too. Checkouts from the legacy store pages have none. Rows from before this change have no source.

Charging follows the same rule since 2026-09-22 (src/lib/server/billing-tier.ts). Before, every paid route asked Discord alone, so a subscriber without the role paid Free prices and could not start Imagine Pro while /app showed their real plan; that day 11 of 396 people with an active plan had a stored role below what they paid for (10 had none). Now the 3D generation route and its status check, remesh, every Imagine image route (/api/v2/images, /api/v2/tattoos, /api/v1/imagine/* through requireImagineUser), the Code agent's chat, upload and deploy, conversion authorize and deduct, and the optimize and livery daily limits all take the higher of the two. The Discord side is read as before (stored roles, then Discord's API), so nobody who had a live role loses it. A tie goes to the paid plan, because Referrer ranks with Standard but prices like Free. The yes or no checks (tools.convert, which prices 3D and conversions at the member rate, and code) ask Discord first as before, then accept a Standard, Pro or Max subscription (not Plugin Pass) if the account is not verification-restricted. past_due still does not count, so a late payer falls back to their Discord role.

Monthly credit plans

Monthly credit plans are subscriptions that add a fresh batch of credits every month without changing the user's tier. Since 2026-10-06 only Spark (500 a month, $7.99) is sold, on the packs row of the workspace's plans dialog; Forge and Powerhouse are off sale and their subscribers keep renewing (see the credit packs doc). On the legacy pricing page they were the "Monthly boost" tab of the "Top up your credits" section (the default tab), badged "lowest per credit", with the note "Refreshes monthly, unused credits expire at renewal".

They are Stripe products in the products table with credit_plan: true metadata and an award_credit amount. The plan names and credit amounts live in the database, not in code (verify the current names and amounts; the store lists them at /api/v1/store/packages).

A credit plan lives alongside a main plan. Its renewal replaces only its own previous grant; a Pro renewal never wipes credit-plan credits and vice versa, and two of the same credit plan each keep their own (since 2026-10-09). Cancel from /api/v2/billing/portal?return=/app. If a judged competition is open, each paid period of a credit plan earns the same entries as buying a pack of that size.

Plugin Pass free trial

The Plugin Pass has a free trial at /store/free-trial/{product or price id}. Only the Plugin Pass product is eligible; any other id returns "Product not eligible for free trial". The trial length in code is 8 days (TRIAL_DAYS = 8) although the session metadata is labelled 14_day_free (verify which is intended). A card is required at sign-up, promotion codes are allowed, and the subscription starts charging when the trial ends unless cancelled from /api/v2/billing/portal?return=/app. No credits are awarded while a subscription is trialing. Success returns to /editor; failure returns to /pricing?error=trial_failed.

Teams and Roblox

A Pro Team groups members under one bill, each seat at the Pro price of $25 a month. Everyone on the team gets Pro access. Teams are created at /app/team with 2 to 100 seats; the Pro card on the pricing page links there with "Need seats for a team? Create a Pro Team". Mixed tiers on one team are not supported. Team seat credits are settled nightly. Since 2026-10-13 team checkout always uses the team seat price, and a checkout that renews an existing team works only for your own team ("Not your team" otherwise). See the billing doc for the team checkout.

One subscription covers every game. The FAQ says "One subscription unlocks the same tier in every game workspace, so a Pro plan bought on the Roblox page is Pro everywhere." The Roblox pricing page at /app?game=roblox&plans=all shows the same plans and Stripe prices with Roblox-flavoured copy; nothing is bought separately per game.

When a prize-pool competition is open, each paid billing period of a main plan adds entries: 5 on Standard, 20 on Pro, 50 on Max, none on Plugin Pass (a competition can override this table).

The plans dialog in the workspace (2026-09-14)

Inside /app the plans open as a dialog over the workspace, not on the pricing page: src/lib/workspace/shell/PlansDialog.svelte, opened through plans.show(source, highlight, section) in shell/plans.svelte.ts. Doors: Plans in the profile menu, Plans on the credits dialog's plan card (the credits dialog closes behind it), Plans in Home's footer, More space under the library's storage line, "Unlimited on any plan" in a Create tool's footer once the day's free conversions are used (Standard drawn out), "See plans" under a generation model the plan cannot use (Pro drawn out), and "Get Standard" or the Standard link in the UV map tool once the day's free map is used (Standard drawn out). The credit packs live at the bottom of the same dialog, and the doors that want credits open it there: the "+" on the credit pill, Get credits on the credits dialog, and every "Get N credits" button in the generators and the refine box. Nothing in the workspace links to /store or /pricing any more; the pricing page itself is unchanged for the rest of the site. One door comes from outside the workspace: the plans section of the discover page (/discover) links to /app?plans=<standard|pro|max|lite|packs>, and the workspace opens the dialog with that plan drawn out (or at the packs) as soon as it loads, then removes the parameter from the address. An unknown value is ignored.

What it shows. The same four tiers as the pricing page, from config/plans.ts, each card in its own colour (a wash of the tier's colour over the head of the card; Standard rose, Pro azure, Max sunset), the name, who it is for, the price a month in large type, a row of pills under it (since 2026-09-27; no terms on the cards, Stripe's page carries those: a pill in the tier's colour anchoring the price to the game's first staple at the plan's own cost ("≈ $1 a model" on Pro, "≈ $0.35 a livery" on Roblox; since 2026-10-14: until then it said what yearly saves, "Save $60 a year" on monthly, a press switching the toggle, and "Saving $60 a year" once there, which now stands on the plate under the button, see the third pass below; the "2 months free" wording of 2026-10-06 went on 2026-10-13: the owner found it confusing); beside it, when a code or a sale cuts the price, "SAVE10 · -10% · first month" or "SALE20 · -20%", with "ends in 2 days" or "3 left" appended when Stripe has an end or a cap on it), then the credits the plan brings, on the head of the card in the same figure as the packs (the coin, "1,500", "credits a month") with "$1.67 per 100 credits" under it (the yearly price and a sale move that number, so a plan and a pack read in one unit), the button, and the plan's feature list with the leading number in bold (the credits line is left out of the list, the head says it). Free shows "50 credits to start". Yearly is the default since 2026-10-13 (the owner: start on yearly so the price shows), with the monthly price struck beside the yearly month; a Monthly / Yearly toggle sits above the cards. Pro carries a "Popular" chip; the plan held carries "Current". A signed-in free account also gets the Plugin Pass row under the grid. Under the tiers, one row of credit packs, each with its own Buy: the three one-time packs by size and the Spark monthly boost beside them (since 2026-10-06; the Once / Monthly switch is gone). Each card reads in the plan cards' order: name and badge, the price as the one large figure, the coin and credits, what that buys in two units for the tool and game in view ("≈ 15 liveries · 31 images", "≈ 3 models · 31 textures"; the first priced by the cost the credit wall handed plans.show as need, shell/pack-units.ts), then one facts line with the per-100 rate and the balance after ("520 after this"); the section line carries "Never expire" once and "20 credits now · a run needs 32"; a quiet line under the row names the ways to pay (see the credit packs doc). The dialog carries no footer of conditions and the cards no replacement warning, cancel line or "click again to confirm" hint (removed 2026-09-27); since 2026-10-06 the yearly button goes straight to Stripe's page, where the year's terms stand over the Pay button. On a phone, when the door asked for the packs (the credit pill's "+", a credit wall), the packs section is drawn above the plan cards and the notice stays on top (max-sm:-order-1, 2026-10-06: phones opened the packs 108 times in a fortnight and bought half as often as desktops).

The cards sell for the game in view (2026-10-13). The owner asked for plans that "convert and sell", vibrant, with "cooler UI components that highlight key takeaways", and that "depend on workspace, e.g. Roblox + FiveM" (Higgsfield's pricing page as the reference for the credits box and the badges). A FiveM / Roblox switch (the games' marks, data-game-tabs) sits beside the Monthly / Yearly toggle, set from the workspace's game cookie each time the dialog opens; pressing the other game is a peek that changes the cards and the pack units, never the rail (PostHog pricing_game_changed). Under each price the credits now stand in a field-fill well: the coin and the count, then what that month buys in the game's two staples at the plan's own prices ("≈ 20 models · 187 textures" on FiveM, "≈ 93 liveries · 187 images" on Roblox; Free's "≈ 3 textures" / "≈ 1 livery · 3 images"), then the plan finder's answer (below), then "$1.67 per 100 credits" (Free's well says what one run costs there instead, "130 credits a model", "32 credits a livery"; shell/plan-takeaways.ts, every number read from pricing.ts and the limit tables). Under the button, "Everything in Standard, plus" leads the takeaways for the game in view (icon rows until 2026-10-14, now the rows of the perk container, see the third pass below; the cut against Free names both staples with their own numbers, never one for the other and never "AI runs"), then whatever feature lines of config/plans.ts are left for that game in the quiet check list (a Roblox card drops the FiveM-only lines: props, YTD and DDS, optimizations, game files, the Code agent, resources; a takeaway drops the line it restates). The band over a paid card grew from a 16% wash to 26% (40% on the steer card), flat (a radial light at its corner lived for a day and went as a glow), with a line of the tier's colour along the top edge, and the whole card is tinted with its colour (6%, 9% on the steer); the steer card alone has its edge in the tier colour itself (30% on the others, 55% on a drawn-out card that is not the steer) and an arrow on its button that slides on hover (a tier-coloured shadow lived there for a morning; the owner read it as a glow and asked for vibrancy instead), while Pro wears "Popular" as the one solid chip (a door that draws out another plan moves the shadow, the edge and the coloured button there and leaves Popular on Pro); the plan with the lowest price per credit at the cycle in view (Max) wears "Best value", and the packs' store badges are drawn in the same casing ("Best value", not the table's "Best Value"). On yearly, the monthly price stands struck beside the yearly month ("$20 $25 / month"; the Plugin Pass row too, "$7.50 $8"), as it did only under a code or a sale before.

The plan finder (2026-10-13, the owner: "interactive points that draw them in"). A strip between the header row and the cards: a count in Digits, a unit select (the game's two staples: Models and Textures on FiveM, Liveries and Images on Roblox), "a month", a slider, the ask in credits at the picked plan's prices ("≈ 1,575 credits on Pro"), and a solid chip with the verdict: the smallest plan under Max whose monthly credits cover that month at its own prices ("Pro fits"); past Pro, "Pro + a pack fits" while Pro plus the largest one-time pack (1,500, PACK_REFERENCE) covers it; then "Max fits"; then "Max + packs fits" (the finish review: one tick past Pro's 20 models used to steer to the $125 plan, when Pro and a pack is the honest answer). FINDER in plan-takeaways.ts sets each unit's start, ceiling and step (models 20, to 60 by 1; textures 150, to 600 by 5; liveries 50, to 300; images 150, to 600; the slider's floor is one step and the ceiling about half again what Pro + a pack covers, so Standard and Pro own most of the track), and the start lands on Pro for every unit. Every card's well answers with a 4px meter and a line: when the plan covers the month, the meter fills in the tier's colour to the share of credits it takes and the line reads "Covers 20 models · 100% of credits" in that colour; when it falls short, the meter fills in subtle ink only as far as the share it does cover and the line reads "Covers 10 of 20 models" (Free: "Covers 0 of 20 models", its 50 credits against the ask). When the pick is a plan plus a pack, that plan's well says so instead of calling itself short ("Covers 20 of 21 · a pack for the rest", in its colour, the bar full), so the card and the chip tell one story. The picked plan becomes the steer (edge, button, arrow, and the solid chip: "Popular" when it is Pro, "Best fit" otherwise, Pro's "Popular" dropping to the wash tone meanwhile) unless a door drew out a plan, in which case the door wins. The count and unit start over on the game's first staple when the game tab changes. The figures on the cards (credits, "≈ 20 models · 187 textures", the finder's count) are Digits, so a drag, a tab or the cycle moves them in view, and the takeaway rows cross-fade on a game switch. PostHog pricing_finder_changed (unit, count, pick, pack) fires once per settled drag. The run counts in the plan wells and on the pack cards group their thousands ("1,875 textures"; countShown in the shell_packs_runs_* messages). Phones hide a card's empty fact rows; desktops keep them so the four buttons stay level. On a phone the header is two rows, the cycle first and full width, then the game marks alone (their names for screen readers and as a tooltip) beside the code field, so the first card is on the first screen.

Perk containers, the depth button and its plate (2026-10-14, third pass). The owner asked for "cooler containers for the special features like Higgsfield has" and "a unique and cool button as a special button v2 component, with depth", pointing at Higgsfield's "Get Plus" (a lime face on a darker lime edge, and under it a plate reading "Save $144 compared to monthly"). Every paid card's button is now ui/DepthButton.svelte: on the steer card a face in the tier colour standing three pixels proud of a darker edge of the same colour (hover lifts it a pixel; a press sinks it onto the edge; it is the button's own body, no blur, so the no-shadow rule on cards holds), and on the other paid cards the same keycap in a quieter material, the card's colour at 14% over a raised tone on its own darker edge (the owner, the same day: an outline button there read as "no style"); under both a plate hanging off the button with the yearly saving: "Saving $60 a year" on yearly, and on monthly "Save $60 a year · go yearly", a press on which switches the cycle (the same PostHog pricing_billing_cycle_changed with via: pill); no plate on the plan held. The saving left the pill row under the price, which now anchors the price to the game's first staple at the plan's own cost ("≈ $1.30 a model" on Standard, "≈ $1 a model" on Pro, "≈ $0.63 a model" on Max; "≈ $0.35 a livery" and so on for Roblox): the monthly figure in view divided by what the month buys (monthBuys, the same arithmetic as the well's "≈ 20 models"), so a yearly month, a code or a sale moves it; the Plugin Pass row keeps its saving pill. The takeaways moved into a perk container under the plate: a box in the control radius tinted with the tier colour, a grid of the colour fading down its head (a texture, not a light), the lead as its title behind a plus glyph, and rows divided by hairlines, each a short label with its selling fact as a badge beside it (one solid badge in the tier colour per row for the fact that sells, a soft wash for a qualifier, and for what Free pays a struck number behind the coin, "was" for screen readers and "Free pays 40 credits" as its tooltip). FiveM: Standard "Model to prop" Free · struck 40, "Conversions" Unlimited, "vs Free" Models -42% (solid) · Textures -38% (soft; the larger cut is the solid one); Pro "Game file conversions" Free · struck 25, "vs Free" Textures -50% (solid) · Models -42%, "Exports" Unlimited · 500 at once; Max "API and CLI access", "Whole folders" 2,000 at once, "Job queue" Highest priority. Roblox: Standard "Designer" Unlimited · Full-size exports, "vs Free" Liveries -38% · Images -38%, "References" 4 per run; Pro the cut, "Job queue" Priority, "Support" Priority · Early access; Max "Job queue" Highest priority, "API and CLI access". Every row is one line at four columns from a 1366px screen: the dialog grew from 1152px to 1440px wide (max-w-[90rem]; the owner saw the badges "pushed down" under the labels) and the two longest labels were cut ("vs Free", "Designer"); on a 1280px screen three rows wrap their badges under the label by overflow. The price-per-staple chip's tooltip gives its arithmetic ("$20 a month over the 20 models it buys"). The light theme's Standard, Pro and Max colours were darkened the same day so 10px badge ink and white-on-colour reach 4.5:1 (theme.css). Standard's "Unlimited optimizations, batch up to 100 files" line stays in the plain list under the container (its row says only "Conversions"). Every number still comes from FEATURE_PRICES, OPTIMIZE_LIMITS, REFERENCE_LIMITS and typicalCost; the messages are shell_plans_perk_* (labels and badges), shell_plans_plate_* (the plate) and shell_plans_each_* (the price-per-staple chip), the old shell_plans_take_* keys gone. Walked in the browser at 1440, 1366×657 and 390 wide, dark and light, both games: the plates end on one line on every card, a press sinks the face 3px, the plate press goes yearly by mouse and by Enter, Tab runs face then plate, no page errors. The finish review asked for eight fixes, all taken: one solid badge per row, "Saving $60 a year" for the plate, the hover sheen removed (the prompt bar's precedent), tighter rows and one-line rows on phones, the light-mode colours, "Game file conversions" with "was" spoken, the title off the uppercase register, the chip's tooltip.

Buttons follow the ladder the way the pricing page's do: "Choose Pro" with no plan held (signed out too, where the click goes to sign-in first and comes back to the tool), "Current plan" disabled on the plan held (with "Change or cancel from Billing" under it, Billing being Stripe's customer portal), "Upgrade to Max" up the ladder and "Switch to Standard" down it, with the warning "Replaces Pro once paid, with no proration. Unused Pro credits go, Standard credits arrive at once." under either. The one coloured button is on the plan the door needs, else on Pro. A plan change is still a new full-price subscription that replaces the old one. The Free card has no button for a subscriber, "Current plan" for a free account, "Sign in" signed out.

Back from a cancelled checkout (2026-10-06). Stripe's back arrow returns to the workspace with ?subscription=cancelled or ?credits=cancelled; the dialog reopens where the person was with "Checkout cancelled · nothing charged" and, for an account that has never paid, the recovery code BACK15 applied (see the billing doc). A returning buyer sees no code and no error: GET /api/v2/billing/promo answers null for a first-purchase code when the signed-in account has paid before (promoOffer(services, code, userId)), and the dialog applies a handed-in code quietly (applyPromo(code, quiet)), drawing nothing for a null. In the fortnight before, 31 people came back this way and none went on.

Checkout is Stripe's page, reached through the workspace's own route. The button asks POST /api/v2/billing/subscribe with the monthly or yearly price id from PLAN_PRICE_IDS and the tool's path, and the browser goes to the Stripe Checkout page it answers with. The route keeps what the pricing page's /store/subscription/{priceId} did: the Stripe customer from the profile (created when missing; an account with no email cannot check out), the sale's promotion code on Pro and Max when Stripe confirms the sale, the replacement warning above Stripe's Pay button when a main plan is held, and a refusal to sell the exact plan already held (409 already_on_plan, shown as the notice line "Already on this plan"). A checkout that will not start at all (Stripe down, a pack no longer sold) shows the same line in its error tone, "Could not start checkout · try again", and the dialog stays. Signed out, the press goes to /auth/start?next= with the tool's path and its search, and comes back to it. Stripe sends the person back to the tool they were in: paid, the dialog "Pro plan active" with "1,500 credits a month · $25 paid" and confetti; cancelled, the plans dialog reopens with the plan they had chosen drawn out and the line "Checkout cancelled · nothing charged". The webhook grants the plan, as before. A sale confirmed by Stripe shows as a chip by the toggle ("20% off Pro and Max · SALE20"), the discounted price with the full one struck beside it on the eligible cards, and "SALE20 at checkout" on their price line. A promotion code typed in the "Promo code" box at the top right (Apply) does the same for the plans it reaches, as a pill under the price with the coupon's duration ("SAVE10 · -10% · first month", "RAINMAD · -15% · for 3 months"), and goes to Stripe with the checkout; staff see an "Admin · Sale" row at the foot of the dialog that switches the site sale on or off and points it at a Stripe promotion code or coupon id (see the credit packs doc for both). Not carried over from the pricing page: the Plugin Pass recovery offer after an abandoned checkout, the comparison table and the team link (the pricing page keeps them).

The pricing page at the live step (2026-09-20). /pricing redirects to /app?plans=all and /roblox/pricing to /app?game=roblox&plans=all: the workspace opens with the plans dialog over it, every plan shown and none drawn out, signed in or not, and the address is cleaned to /app. Until live the pricing pages are untouched. Analytics source pricing.

The plan follows the payment without a reload (2026-09-20). Stripe's redirect usually reaches the workspace before its webhook has written the subscription, so the load that draws the return read the account a moment before it was on the plan, and the person who had just paid was drawn as Free (the day's limits, and the Upgrade button) until they happened to navigate. On ?subscription=success the (app) layout now re-runs its loads four and twelve seconds later (invalidateAll), beside the balance refresh that was already there; loadMe reads the tier again and credits.sync takes it.

Analytics. The same PostHog events as the pricing page (pricing_section_rendered with section, pricing_billing_cycle_changed, pricing_yearly_confirm_shown / _accepted / _cancelled, pricing_plan_selected, payment_subscription_checkout_started) with surface: workspace and a source naming the door (profile-menu, credits, credit-pill, home, storage, convert-quota, generate-model, generate-image, refine, uv-limit); the server adds payment_subscription_checkout_created when the Stripe session exists. Since 2026-10-13 every event carries game (the tab in view), pricing_game_changed fires when the tab is pressed and pricing_finder_changed (unit, count, pick) once per settled drag of the plan finder.

On a laptop (2026-09-21). The plans dialog in /app is about 1000px tall with the credit packs under the plans. On a screen under 1080px of browser height its padding tightens (short: in theme.css), so at 1920 x 1080 everything fits without scrolling. On a MacBook the four plans and the Plugin Pass fit and the credit packs are one scroll down inside the dialog; that scroll is expected, nothing is cut off.

Plan colours

Each tier has one colour, the band it wears on the plan badge, the avatar ring and its card in the plans dialog. Decided 2026-09-14, as tokens in src/lib/workspace/theme.css (--app-plan-*, dark and light values) and named in src/lib/workspace/plans.ts: Free subtle grey, Plugin Pass mint, Standard rose (a pinkish red), Pro azure (a clear blue), Max sunset (a warm orange), Supporter lavender. None is the site's brand indigo: the brand marks the primary action and the focus ring, so a tier must never look selected; Pro was on the brand hue before that day and was moved off it. The legacy pricing page keeps its own accents (text-standard-primary, text-primary-100, text-credit-primary).

Common questions

What is the difference between Standard and Pro? Standard is $15 a month with 750 credits every month; Pro is $25 a month with 1,500. Both make conversions and optimizing unlimited and include the Photoshop and Photopea plugin. Pro adds the lowest credit prices on every AI tool, a priority queue on every job, free game file conversions, bigger batches (500 files in Optimize against 100), priority support and early access. In the workspace library Standard has 10 GB, keeps unpinned uploads 90 days after their project was last used and what tools and AI made for good, keeps 10 versions of a project and allows 50 pins; Pro has 50 GB, nothing expires and a project keeps 30 versions (Max 100). Free keeps uploads 7 days and what tools and AI made 30 days, 3 versions a project (since 2026-10-02; before, everything went 7 days after upload). Deploying to a server and uploading a ZIP to the Code agent need Pro.

Where do I see the plans inside the workspace? Open your avatar at the top right and choose Plans, or click Plans on the credits dialog. The plans open over the workspace with the credit packs under them; the button on a card takes you to Stripe's checkout and brings you back to the tool you were in.

Can I cancel any time? Yes, from the "Billing portal" link in your user menu (/api/v2/billing/portal?return=/app). You keep access until the end of the period you already paid for. Nothing is refunded.

What happens to my credits if I upgrade? The new plan replaces the old one the moment it is paid. Unused credits from the old plan are removed and the new plan's full monthly credits arrive straight away. Pack credits and credit-plan credits are not affected.

Why does the yearly button ask me to click twice? Yearly is one non-refundable payment for 12 months. The first click shows the real charge, the second click confirms it.

Does a plan cover both FiveM and Roblox? Yes. One subscription is the same tier in every game workspace.

Does the Photoshop plugin need my Discord role? Not since 2026-09-20. An active Plugin Pass, Standard, Pro or Max subscription opens the plugin on its own; the Discord role is only how accounts without a subscription of their own (referrers, roles given by staff) get in.

I subscribed but my Discord role is missing. Roles are assigned by the Stripe webhook to the Discord account linked to your Zoov.dev profile. Make sure you are in the Zoov.dev Discord and signed in with the same Discord account, then ask staff to check the webhook log. Since 2026-09-22 a missing role no longer changes your prices or plan features on the site: they follow your subscription. The role still matters for Discord itself (channels, the Early Adopter role).

Can I switch from monthly to yearly? Yes. Use the billing portal to change the billing interval on the same plan; the pricing page shows "Current plan" for a tier you already hold.

Languages

Since 2026-09-20 this part of the site is available in English, French, German, Spanish, Portuguese, Polish and Dutch. It follows the browser's language on a first visit, and the language menu (the icon beside the profile in /app, or in the top navigation on public pages) changes it. Nothing about how it works, what it costs or what a plan includes differs by language; only the words do. File names, format names (GLB, YDR, YTD), product and model names, code, and some error lines that come from the server stay in English. Details and known gaps: Languages and translation.

Checkout starts a little sooner (2026-09-28)

The workspace's checkout routes return Stripe's address without waiting for the analytics event about it; the event is sent after the response. Nothing else about checkout changed.

Renewals that brought no credits (2026-10-02 to 2026-10-09)

From 2026-10-02 a monthly renewal of any plan (Pro, Standard, Max or a credit plan) charged the card and kept the plan active but added no credits for the new month. The first month's credits arrived as normal. Fixed on 2026-10-09: each renewal again adds that month's credits. A subscriber who renewed in that window and says their credits never came is right; staff restored the missing month on 2026-10-09 (as a normal renewal would: the month's full allowance, last month's unused credits gone). Do not tell them to wait or resubscribe.

The same fault stopped yearly plans' monthly credits: a yearly subscriber got the first month at checkout and nothing after. From 2026-10-09 each month arrives again (the current month on the first nightly run or page visit). Months before that were not paid; send any yearly subscriber who asks about them to staff.

Monthly credits reset at renewal. Plan credits are temporary: each renewal (and each month of a yearly plan) replaces what is left of that plan's previous month with the new month's allowance. Pack credits are permanent and never reset. Each subscription has its own allowance: two Sparks give two monthly batches, and one renewing or ending leaves the other's credits alone (since 2026-10-09; before, one renewal of a pair wiped the other's credits). The credits dialog lists every batch that will expire and its date, and the plan's renewal date.

A plan for a day, and a half-price first month (2026-10-16)

Two offers touch the plans; both are put to a free account only by the offer dialog (docs/kb/offers.md), never sold from the plans dialog.

The Standard day pass ($2.99) holds the Standard plan for 24 hours with no subscription: unlimited conversions and optimizations, the Designer without its daily minutes, Standard's credit prices on AI runs, full-size exports, four reference pictures a run, the plugin. It brings no monthly credits and no Discord role, and it ends on its own; two passes in a row are 48 hours. The workspace reads it beside the subscriptions, so for those hours the top bar, the limits and the prices all say Standard.

The half-price first month is the monthly Standard plan with the promotion code HALFMONTH attached (50% off the first month, Standard only, first purchase only): $7.50, then $15 a month, cancel any time from Billing. Stripe refuses the code to anyone with an earlier payment on the account; the dialog then says the offer is no longer available.

Topics planssubscriptionpricingupgradecancelyearlyplugin passpromaxstandardteamroblox

Something missing? Ask on Discord