Account and billing
Signing up and signing in, what each plan costs and includes, managing a subscription and card, where invoices live, and how to get your data out.
An account is an email, a username and a password. It holds your generation credits, your plan, your orders and — if you use the print API — a card on file. This page covers every way in, what each plan actually includes, how to change or cancel a subscription, where the receipts are, and what you can and cannot do about your data.
Creating an account#
Registration is one form at /auth/signup and then a six-digit code by email. The code is what turns a registered account into one that can sign in, so nothing is usable until you enter it.
- 1Register
Name, username, email, password and password confirmation. All five are required, and the two passwords have to match.
- 2Enter the code we email you
Six digits, valid for 10 minutes. Five wrong attempts destroy the code and you have to request a new one. A code can be re-sent, but only three verification emails go to one address in any 15 minutes.
- 3You are signed in
Verifying creates your credit balance with 5 free generation credits and signs you in through the same password provider you would use next time.
/api/auth/signupNo authOne endpoint, three actions: register, verify, resend.
curl -X POST https://x3dstudios.com/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"action": "register",
"name": "Ada Lovelace",
"username": "ada_l",
"email": "[email protected]",
"password": "correct-horse-battery",
"confirmPassword": "correct-horse-battery"
}'
# => {"step":"verify","email":"[email protected]"}| Field | Rule |
|---|---|
| The identity of the account, stored lowercased. One account per address. | |
| Username | 3 to 20 characters, lowercase letters, digits and underscores only. Must be unused. |
| Password | At least 8 characters. Stored as a salted scrypt hash, never in plain text. |
Signing in#
There is exactly one sign-in method: a password. The first field accepts either your username or your email address, so whichever you remember works. Sign in at /auth/login; /auth/signin redirects there. A session lasts 30 days, and signing out from /profile ends it on that device only.
Forgot the password: /auth/forgot-password emails a six-digit code, and the second step takes that code plus a new password of at least 8 characters. The first step answers the same way whether or not the address has an account, so it cannot be used to find out who has one.
/api/auth/reset-passwordNo authaction "send-code" emails a code; action "reset" takes email, code and the new password.
Changing a username or password while signed in is done from /profile, or directly against the profile endpoint. Changing a password requires the current one.
/api/profileSigned inSend username, or currentPassword plus newPassword. GET returns name, username, email and createdAt.
Plans#
Two subscriptions exist, both monthly, both cancellable at any time. Every account, plan or not, starts with 5 generation credits. Generation credits and print credit are separate balances: credits are spent generating models, print credit is a dollar amount that comes off a print order.
| No plan | Maker | Pro Studio | |
|---|---|---|---|
| Price | $0 | $19 / month | $49 / month |
| Generation credits | 5 to start, then buy packs | 100 each month | 400 each month |
| Print credit | None | $5 each month | $10 each month |
| Print discount | None | None | 10% off Print & Ship orders |
The credits arrive when each monthly invoice is paid, granted once per invoice, so a retry or a duplicate webhook cannot double-grant. Cancelling clears the plan and its print credit as soon as Stripe reports the subscription ended; generation credits already in your balance stay there.
The Enterprise card on /pricing is a conversation, not a plan you can buy — checkout accepts only maker and pro. Use /contact for dedicated capacity, bulk SLAs or white-label API terms.
Credit packs#
Credits can be bought outright without a subscription. A pack tops up the same balance a plan grants into.
| Pack | Credits | Price | Per credit |
|---|---|---|---|
| small | 60 | $10 | $0.17 |
| medium | 150 | $22 | $0.15 |
| large | 400 | $50 | $0.13 |
/api/billing/checkoutSigned inOpens a Stripe Checkout session for a subscription or a credit pack.
typestringrequired- Anything else is a 400. Print orders are explicitly rejected here — they go through /api/print-order so the price is calculated from the stored model.
subscriptioncredit_topup planstringoptional- Required when type is subscription.
makerpro packstringoptional- Required when type is credit_topup.
smallmediumlarge
The response is { url, sessionId } — send the customer to url. Without a session the endpoint returns 401, and if payments are not configured it returns 503 rather than a broken checkout page.
Changing a plan or a payment method#
Upgrades, downgrades, cancellation and card changes all happen in the Stripe billing portal rather than in a form here, so card details never touch this site. Ask for a portal link and open it.
/api/billing/manageSigned inReturns { url } for a Stripe billing portal session that comes back to /pricing.
An account with no Stripe customer id on record answers 400 with "No active subscription found. Please subscribe first." Only a subscription writes that id: a credit pack is a one-off payment and the card saved for the print API is held separately, so neither of those opens the portal. Subscribe once and it opens from then on.
Receipts, invoices and statements#
There are three places money is shown, and each answers a different question.
- Payment History on /orders — your last 50 Stripe charges with the amount, date, status and a Receipt link straight to Stripe's hosted receipt. The list is charges only; a refund shows up in Stripe's receipt rather than as its own row.
- /orders/statement — a printable statement for any date range, defaulting to the range you have filtered on the orders page. It lists date, order, items and amount, totals them, and shows anything not charged (cancelled, refunded, failed) in a separate list rather than hiding it. Issued as Xpress 3D Print, Austin, Texas. There is no PDF library behind it: the Print / Save as PDF button uses your browser's print dialog, with the page furniture hidden.
- The Stripe billing portal, via /api/billing/manage — subscription invoices and their payment status.
A card on file for the print API#
Orders submitted through the developer print API are charged automatically on submission, so a saved card is a precondition for having a key at all. Both live on /profile.
- 1Add the card
The Add a card on file button opens a Stripe-hosted setup page and returns you to /profile#api. Nothing is charged when you save it.
- 2Generate the key
The plaintext key is shown exactly once — copy it then. Afterwards only its prefix is displayed, because only a hash is stored. Generating again rotates the key and invalidates the old one.
- 3Revoke when you are done
The revoke button clears the key immediately. Any request using it fails from that moment.
/api/account/api-keySigned inCreates or rotates the print API key. Returns 402 with code CARD_REQUIRED when no card is on file.
The card status endpoint reports the brand, last four digits and expiry of the saved card, which is what the badge on /profile reads. Connected Chrome extensions carry a separate token type and are revoked separately, individually or all at once. See /docs/api/keys and /docs/integrations/chrome-extension.
Getting your data out, and closing the account#
Being straight about this: there is no delete-my-account button and no one-click export. What exists is the following, and anything beyond it is a person at [email protected].
- Order history: /orders lists your last 50 orders, and /orders/statement turns any date range into a document you can save as a PDF.
- Payment records: each charge has a Stripe receipt link, and subscription invoices sit in the billing portal.
- Credentials: change your username or password at /profile at any time.
- Access: revoke the API key from /profile, and sign out there to end the session on a device. A connected extension is revoked with POST /api/extension/revoke from a signed-in browser — /profile has no extension section yet.
- Deletion: email [email protected] from the account's address. Financial records attached to completed orders are kept for accounting.