Credit packs and sales

Updated Oct 16, 2026 Open the tool

Credit packs are one-time purchases of permanent credits, sold next to the subscription plans on /app?plans=all and from the header credits badge. A site-wide sale, when one is running, is a Stripe promotion code that the store applies automatically to every pack except the smallest.

The packs and what they cost

Credit packs are one-time purchases. There are three since 2026-10-06 (four before), from the reference snapshot in src/lib/config/plans.ts (PACK_REFERENCE, which also carries each pack's row id in the products table: 20, 21, 11). The ladder was cut on the sales of the fortnight after the September repricing: only 400/$12.99 and 1,500/$24.99 sold, 4,000 and 12,000 sold nothing, first buyers took the smallest pack 83% of the time, repeat buyers came back for the same small pack within two days, half a pack sat unused after 60 days, and one-off cards failed on insufficient funds at $12.99 about once for every two that passed. So the door got a $5.99 pack, the middle grew from 400 to 500, and 1,500 moved from $24.99 to $29.99 so a Pro month ($25, the same 1,500 credits plus every Pro feature) stays the better buy of 1,500. The retired packs (products 10, 12, 16; Stripe products archived) stay in the table as active = false. The credits per pack grew on 2026-09-14 at the same prices (300 / 1,000 / 3,000 / 8,000 before); npx tsx scripts/apply-credit-amounts.ts --apply writes the new amounts, names and feature lines to the products table and the Stripe product names, so until it has run the store still sells the old counts:

Pack Credits Price Per 100 credits
Starter 150 $5.99 $3.99
Builder 500 $14.99 $3.00
Creator 1,500 $29.99 $2.00

Against the plans per 100 credits: Standard $2.00 (the same as Creator), Pro $1.67, Max $0.99; the Spark boost $1.60. Builder carries the "Popular" badge (the one coloured Buy in the row), Creator "Best Value". A Roblox livery sheet at standard quality is about 30 credits, so the packs read as five, sixteen and fifty liveries.

What a card says (2026-10-06, shell/pack-units.ts). A pack card reads in the plan cards' order (the owner's call the same day: the first cut zig-zagged, a small chip, a big number, small words, a big price): the pack's name (Starter, Builder, Creator, Spark) with the store's badge; the price as the one large figure (28 px, with "/ month" on the boost, and the struck list price and the cut when a sale or code reaches it); the coin and the credits as the allowance line ("500 credits", "500 credits every month"); what that buys in two of the things people make here, "≈ 15 liveries · 31 images" on Roblox and "≈ 3 models · 31 textures" on FiveM: the tool in view first (the door the dialog opened through, else the mode on screen: erlc liveries, image images, design textures, prop and convert models, clothing, outfit and packs clothing sheets, tattoo tattoos), priced by the cost the credit wall handed plans.show as need (every wall passes it: generate-livery, erlc-result, generate-image, refine, image-tool, generate-clothing, tattoo-tool, generate-model), then the game's other staple at a typical run's cost from the pricing table at Free's price and standard quality (a livery or clothing sheet, a one-input image or texture, a textured Meshy model at 130); a unit the pack cannot buy one of is left off; then one quiet facts line, "$3.00 per 100 credits · 520 after this" (the balance plus the pack, signed in) or on the boost "$1.60 per 100 credits · Unused expire at renewal"; then the Buy. The section line carries "Never expire" once and, signed in, "20 credits now · a run needs 32" on the right; under the row a quiet line names the ways to pay (card, Apple Pay, Google Pay, iDEAL, Bancontact, Link, Stripe checkout). The "N% less per credit" pill and the per-card "Never expire" are gone. Since 2026-10-13 the game the units follow is the dialog's FiveM / Roblox tab (set from the workspace's game when the dialog opens; see the plans doc, "The cards sell for the game in view"), not the cookie alone, and the counts group their thousands ("1,875 textures", countShown in the shell_packs_runs_* messages); typicalCost(unit, tier) prices a plan card's well at the plan's own rates while the packs keep Free's.

The live list comes from the products table through GET /api/v1/store/packages, which returns only active products, so the store can differ from this table if a pack is repriced or switched off (verify the current list against that endpoint before quoting a price). Each card shows the credit amount, the price, and "{price} per 100 credits" so sizes are comparable. The pack with the lowest price per credit is badged "Lowest per credit" and the recommended pack (the third one, or the largest during a sale) is badged with its product badge, for example "Popular" or "Best Value".

For comparison the pricing page notes that "A 1,500 credit pack is $29.99 on its own." (since 2026-10-06; $24.99 before) next to the Pro plan, which is $25 with 1,500 credits a month plus every Pro feature.

Pack credits are permanent

Credits bought as a pack are permanent. They never expire, they are not reduced by a plan renewal, and they survive cancelling a subscription. The one-time tab of the store carries the trust points "Stripe checkout", "One payment", "Credits never expire". The pricing FAQ says "Credits you buy as a pack are permanent and never expire, so a pack is the right choice for a one-off project and a plan is the right choice for steady work."

Because spending always drains temporary plan credits first, pack credits sit untouched until the plan credits are gone. Pack credits are added by the Stripe webhook as permanent once per payment, so a retried webhook cannot double-credit.

Packs do not change the user's tier. A Free user who buys a pack still pays Free-tier credit prices per job; users below Pro see the banner "Plans include credits and lower every credit price".

Where and how to buy a pack

Packs are sold in the "Top up your credits" section of /app?plans=all, in the credit store modal opened from the header credits badge ("Buy credits"), and in a compact three-pack strip inside some workspace pages. The section has two tabs, "One-time packs" and "Monthly boost"; the monthly tab opens by default.

Signed-out users see "Sign in to buy". Signed-in users see "Buy 1,500 credits" (or the pack's amount). With a saved card the button charges it after a "Confirm Purchase" modal; without one it opens Stripe Checkout in a popup. Both paths are described in the billing doc.

Error strings a user may paste: "Please sign in to buy credits.", "Popup blocked. Open the secure checkout link to continue.", "Your previous payment is still being finalized. Please wait for the credits to appear before starting another checkout.", "Payment received. Credits should appear shortly.", "Packages could not load" with a "Retry" button, and "No credit packages available right now."

Packs in the workspace (2026-09-14)

In /app the packs are the bottom of the plans dialog (see the plans doc), reached from the "+" on the credit pill in the top bar, Get credits on the credits dialog, and every "Get N credits" button a generator or the refine box shows when the balance is short. The list comes from GET /api/v2/billing/packs (no sign-in needed): the active one-time packs smallest first, then the monthly boosts, each with its credits, price, badge and, during a sale, the sale price. A "One-time / Monthly boost" toggle switches between the two kinds when boosts exist. Each pack is a card with the credit count, the store's badge ("Popular", "Best Value", "Studio Choice"), the price (struck full price and "-20%" on sale; "/ month" for a boost), a row of pills (since 2026-09-27: "Never expire" on a one-time pack, and "49% less per credit" measured against the smallest pack in view, when the difference is 5% or more) and "$1.67 per 100 credits"; each pack has its own button, "Buy · $24.99" or "Subscribe · $16.99 a month" (the pack the store badges Popular gets the coloured one), so a pack is one press; signed out the press goes to the sign-in first.

Buying asks POST /api/v2/billing/packs/checkout { packId, returnTo } and goes to the Stripe Checkout page it answers with: a full-page visit, not the store's popup. The route keeps what POST /api/v1/payments/checkout does (the Stripe customer from the profile, the test or live price id by the key in use, the award_credit metadata the webhook reads, the card kept for later when the buyer ticks Stripe's box (forced before 2026-10-06, which hid iDEAL, Bancontact, Przelewy24 and EPS; see the billing doc), a one-hour session with recovery (two hours before 2026-10-06), the sale's promotion code on eligible packs, subscription mode for a boost). Stripe brings the person back to the tool they were in: paid, the dialog "Payment received" with the credits and the amount, and confetti (the webhook grants the credits and the balance in the top bar follows on its own); cancelled, the plans dialog reopens at the packs with "Checkout cancelled · nothing charged" and, for an account that has never paid, the recovery code BACK15 applied (2026-10-06; see the billing doc). The session-status poll stays on the legacy store only.

Buying with a card on file (2026-09-14). In the workspace's Credits dialog a one-time pack can be paid without Stripe Checkout when Stripe already keeps a card for the account (any card saved by an earlier Checkout, which stores it for later). The dialog reads the cards through GET /api/v2/billing/card and shows the first one under the packs ("Visa ···4242 on file · Change card", the portal). The first press on a pack's Buy turns it into "Charge ···4242 · $24.99" for 10 seconds; the second press charges it through POST /api/v2/billing/packs/charge { packId, paymentMethodId }, which checks the card belongs to the account's Stripe customer and confirms a PaymentIntent for the pack's price with the same metadata a Checkout pack carries (user_id, packageId, type: credits, award_credit), so the webhook's payment_intent.succeeded handler grants the credits once (stripe-intent:<id>). Paid: the dialog closes, confetti falls over the whole screen, the balance in the top bar counts up by the credits bought, and a toast reads "Paid $24.99 · Visa ···4242 · 1,500 credits". The workspace holds the higher balance for up to a minute while the webhook grants the credits (the balance is asked for again after 4 and 12 seconds), so it never dips back. When the bank wants a verification (3-D Secure) the route answers requires_action with the client secret and the dialog finishes it in Stripe's own window (stripe.handleNextAction). A decline comes back as 402 with Stripe's decline code, worded as a fragment in the error tone: "Card declined · Visa ···4242", "Insufficient funds · Visa ···4242", "Card expired" with Change card, "Bank check failed", otherwise "Payment failed". A pack the sale covers is charged at its sale price, the one the dialog shows (the sale's code and percent go into the payment's metadata, since a promotion code only exists on Checkout). Monthly boosts still go to Checkout (a boost is a subscription), and so does every pack when no card is on file ("Stripe checkout · card kept for next time"). The card charged is the customer's default card when Stripe has one; cards past their expiry month are never offered. Each armed press carries its own idempotency key, so a double press or a retried request can never charge twice. The Credits dialog lists the one-time packs as rows (the credit count with the store's badge as a chip, "$1.67 per 100", the Buy; on a phone the packs come right under the balance) with a Monthly boosts link that opens the plans dialog at the packs.

On a laptop screen the credit packs sit below the plans inside the plans dialog and may need one scroll to reach (2026-09-21: the dialog tightens under 1080px of browser height, and fits whole at 1920 x 1080). The credit pill's + opens the dialog already scrolled to the packs.

Monthly boost plans

Monthly boosts are subscription products that add credits every month without changing the user's tier. Since 2026-10-06 one is sold, Spark, 500 credits a month for $7.99 (product 17), drawn on the same row as the three one-time packs in the workspace's plans dialog with a "Billed monthly · cancel any time" pill (the Once / Monthly switch is gone: in the five weeks before, Spark was the pack most likely to be paid for once pressed, 77% of its checkouts, with 29 subscribers, and it sat behind a second tab). Forge (1,200 for $16.99, 8 subscribers) and Powerhouse (3,500 for $44.99, none) are off sale (products 18 and 19 active = false, their Stripe prices archived); the subscriptions already on Forge keep renewing. On the legacy pricing page the boosts were a "Monthly boost" tab badged "lowest per credit", each card "credits, every month" with the price per month and the note "Refreshes monthly, unused credits expire at renewal".

These plans are Stripe products with credit_plan: true. Their names and credit amounts are set in the products table, not in code (verify the current plans at /api/v1/store/packages). They coexist with a main plan, their credits expire at each renewal plus a 3 day grace, and cancelling one from /store/portal removes only that plan's credits. Sale badges never apply to monthly boost plans; the sale covers one-time packs and the Pro and Max subscription tiers only.

How a sale works

A sale is switched on by staff from the plans dialog (since 2026-09-27) and enforced by Stripe. The setting lives in the site_settings table under the key store.sale: whether the sale is on, and the Stripe promotion code (for example SALE20) or the Stripe coupon id it applies. Before any setting was saved, src/lib/config/sale.ts was the seed (active, code); once a setting exists the config's active and code are never read again. The rules stay in the config: the smallest credit pack is excluded (yes), and only the pro and max subscription tiers are included. As of 2026-09-27 no sale is running.

Stripe is the source of truth. Even with the sale switched on, the server looks up the promotion code or coupon on Stripe once a minute and treats the sale as off if it is missing, deactivated, expired or fully redeemed, if it takes an amount off rather than a percent, or if it was minted for one customer. When the coupon is limited to certain Stripe products, only those plans and packs show the sale. The percent shown in the UI is the coupon's real percent from Stripe. GET /api/v1/store/sale returns { active, code, percentOff } and every sale element on the site reads from it; in /app the packs route carries the same sale.

During a sale the store shows a red "SALE" pill: "{percent}% off selected packs with code SALE20 applied at checkout", a "SALE -20%" badge on eligible pack cards with the struck-through price, and "Code SALE20 applied at checkout" under the price. The Pro and Max plan cards get the same badge and "{price} a month before the sale". Nobody types the code: checkout attaches the promotion code automatically, which also means Stripe's own promo code box is hidden on those sessions. The saved-card one-click path is disabled for on-sale packs because it cannot apply a code, so they always open Stripe Checkout.

The smallest pack (by credits, the Starter) is never on sale. Plugin Pass and Standard are never on sale. Monthly boost plans are never on sale.

Ending or starting a sale

Staff start or stop a sale from the plans dialog in /app without a deploy. A signed-in account with the Discord developer role sees one more row at the foot of the dialog, "Admin · Sale": a switch, a box for a Stripe promotion code or coupon id, and Save. Save asks Stripe first: a code or coupon Stripe does not know is refused with Stripe's reason and nothing is saved; an amount-off coupon or a code minted for one customer is refused too, because a sale needs a percent off. A valid one is live at once (the toast reads "Sale on · 20% off · SALE20"), and the line beside the row says what Stripe makes of it: "Live · 20% off · SALE20 (promotion code) · every eligible plan and pack · set here", or "Off · Promotion code SALE20 is deactivated in Stripe · set here". Switching the sale off needs no code.

To stop a sale everywhere at once, switch it off in that row, or deactivate the promotion code in Stripe; the second takes effect within a minute because the server re-checks every 60 seconds and the dialog reads the sale each time it opens.

To run a sale, create a percent-off coupon in Stripe (optionally limited to certain products, with an expiry or a redemption cap so it switches itself off), and either a promotion code on it or just the coupon; then paste the code or the coupon id in the row and switch it on. With a promotion code the dialog shows that code ("SALE20 at checkout"); with a bare coupon id it shows the coupon's name from Stripe, so give the coupon a short name. Do not announce a percentage the coupon does not carry; live pricing uses Stripe's number.

Abandoned checkouts can carry a separate recovery code in the Discord DM (internal env var), which is independent of the site sale.

Promo codes on the plans dialog

A promotion code can be typed on the plans dialog in /app (since 2026-09-27), in the "Promo code" box at the top right, then Apply. Stripe prices it: a code Stripe will redeem turns into a chip, "SAVE10 · 10% off" (or "SAVE5 · $5 off"), the plans and packs it reaches show the cut price with the full price struck through, and a pill under a plan's price reads "SAVE10 · -10% · first month" (or "first year" on yearly billing, "for 3 months", or nothing after the cut when the coupon lasts forever) with "ends in 2 days" or "3 left" appended when Stripe has an expiry or a redemption cap on the code; the chip at the top carries the same. A code Stripe does not know, has switched off, that expired or is used up shows "Code not valid" under the box. A code Stripe accepts but that is limited to products not on the dialog shows the chip with "Code valid · not for these plans or packs". A coupon id is not a code: only promotion codes work in this box.

The code goes with the checkout: Buy or Choose sends it to /api/v2/billing and Stripe's Checkout page opens with the discount already on it (Stripe's own promo box is then hidden, because Stripe allows one or the other). Where the code reaches a plan or a pack it replaces the site sale on that item; elsewhere the sale still applies. If Stripe stops taking the code between the dialog and the checkout, the dialog shows "Code no longer valid · removed" and the prices go back. The applied code stays for the browser session, so a cancelled checkout comes back to the same prices, and the × beside the chip removes it. A link into the workspace can carry a code: /app?promo=SAVE10 opens the plans dialog with it applied, which is how an email or a post hands one out. Codes typed here are only for Stripe Checkout; the Credits dialog's card-on-file Buy does not take one.

Competition entries from packs

When a prize-pool competition is open, buying a pack adds competition entries: 10 entries for 1,000 credits or more, 25 for 3,000 or more, 50 for 8,000 or more. The 300 credit Starter pack adds none. A monthly boost plan counts as a pack purchase of its credit amount on every paid period.

Entries are capped per person for the competition (10 in a judged contest, otherwise four Max periods' worth), granted once per payment, and the user receives a Discord DM when they land. The success page after a purchase can show "You're eligible for the {prize} prize pool" with "Your purchase comes with competition entries." and an "Enter the competition" button when the buyer has not submitted yet. Outside a competition nothing is granted and nothing is shown.

Common questions

Where do I buy credits inside the workspace? Press the "+" next to your balance at the top right, or Get credits on the credits dialog. The packs open under the plans; pick one and press Buy to go to Stripe's checkout.

Do pack credits expire? No. Credits bought as a pack are permanent and are kept if you cancel your plan.

Does buying a pack lift the Designer's daily limits? No. A pack only adds credits. The Designer's Free limits (30 editing minutes, 1024 exports, 3 YTD or DDS and 3 models in 3D a day, 3 saved designs) are lifted by Standard, Pro or Max (since 2026-09-23).

Which is better value, a pack or a plan? A Pro plan is $25 with 1,500 credits a month and lowers the credit price of every AI job; a 1,500 credit pack is $29.99 and leaves you on Free-tier prices. Packs suit a one-off project.

Is there a discount code? Only when a sale is running. During a sale the code (for example SALE20) is applied automatically at checkout on every pack except the smallest and on the Pro and Max plans. Right now there is no sale.

I have a promo code, where do I enter it? In /app, open the plans (the "+" on the credits, or Plans in the profile menu) and type it in the "Promo code" box at the top right, then Apply. The prices update before checkout and the code goes to Stripe with the purchase. "Code not valid" means Stripe does not know it, it has expired or it has been used up.

Why did the sale badge not apply to the Starter pack? The smallest pack is always excluded from sales.

Do I get competition entries for buying credits? Only while a prize-pool competition is open: 10 entries for 1,000 credits, 25 for 3,000, 50 for 8,000. The 300 pack adds none.

Does buying a pack unlock Pro tools? No. Packs add credits only. Tools and lower credit prices come with a plan.

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.

Two packs sold only as offers (2026-10-16)

Two credit packs exist that the plans dialog and the Credits dialog never list: the first pack (60 credits for $1.99, for an account that has never paid, once) and the top-up (80 credits for $2.99, for someone short of a run). They are only ever put to a person by the offer dialog, after the plans dialog was closed without buying or on a return visit with fewer than 32 credits, and they cannot be asked for. Their credits are permanent like any pack's. The sale never covers them, and they are never "the smallest pack" the sale skips: the Starter pack (150 for $5.99) keeps that place. The whole system, including the Standard day pass and the half-price first month, is in the offers article (docs/kb/offers.md).

Topics creditspackspackagesstoresalepromo codediscountcompetition entriesmonthly boost

Something missing? Ask on Discord