X3DStudios

Pricing model

How a print quote is computed at X3D: the all-in per-gram rate, the quality multiplier, gram rounding, bulk tiers and shipping, with a worked example.

A print is priced by weight. One all-in rate per gram covers the filament and the normal machine time, billable weight rounds up to the whole gram, and there is a $1.00 minimum per part. This page gives you the whole calculation, so you can work out your own quote before you upload anything.

The formula#

One part, one order
billable grams = ceil(grams)
per part       = billable grams x rate per gram x quality factor
order subtotal = max(per part x quantity x bulk factor, $1.00 x quantity)
order total    = order subtotal + shipping

Everything else on this page is either where the grams come from or which number goes into which slot. Nothing is added for setup, file handling, supports or brim — supports and brim are plastic, so they arrive as grams and are paid for as grams.

Two discounts can come off that total at the till, and neither is part of the quote above. An account that has never paid us for anything takes 10% off the goods at cart checkout — postage excluded — and a gift card can be applied on top of it. A Pro account takes 10% off an order placed straight from /print with its Order button, postage included, and any print credit on the account then comes off what is left.

Rate per gram#

MaterialAPI keyRate per gramDensity
PLApla$0.121.26 g/cm³
PETGpetg$0.121.27 g/cm³
ABSabs$0.121.04 g/cm³
ASAasa$0.141.07 g/cm³
Flexible TPUtpu$0.131.21 g/cm³
All-in USD per gram — filament and normal machine time together.

Density is part of the price, not a footnote. The same model in ABS weighs about 18% less than in PETG, so at the same $0.12/g it costs about 18% less to print. See /docs/materials for what each plastic is actually good for.

A colour we do not stock has a $0.20/g floor
Twelve colours are held on the shelf and print at the rate above. Any other colour is charged at a minimum of $0.20 per gram whatever the material, because the spool has to be bought in for that order. It is a floor rather than an override, so a material that costs more than $0.20/g keeps its own rate. Leaving the colour blank is not a custom order.

Quality factor#

QualityLayer heightPrice factorEffect on a $0.12/g material
Standard0.2 mm1.00$0.12 per gram
Premium0.1 mm1.75$0.21 per gram

Premium halves the layer height, which roughly doubles the machine time for the same weight of plastic. The factor multiplies the per-gram charge; it does not add an hourly line.

Where the grams come from#

Two sources, and the quote says which one it used. Measured always beats modelled.

  • Measured — the file is sliced by OrcaSlicer with the real Bambu profile and the filament volume it reports is converted to grams with the material's density. This is what the quote uses wherever a slice can be run. It takes ten seconds to a minute, so the first number on the page may still be the estimate.
  • Estimated — a geometric fallback used before a slice lands: model volume x (0.30 + 0.70 x infill), then x density. The 0.30 is the solid perimeter walls; infill fills the rest. Requested infill is clamped to 5–100% and defaults to 20%.
  • A pre-sliced upload (.gcode, .3mf, .gcode.3mf) is always measured — the grams and hours come out of the file's own header, and they already contain every purge, support and brim.
Checkout will not sell an unmeasured print
The volume estimate undercounts thin, wall-heavy parts — one observed case slices at 21 g on the plate against a 12.9 g estimate — so charging from it would sell below the advertised rate. If a slice has not landed yet, cart checkout answers 409 with measuring: true and the cart holds the button closed until it has. Above 35% requested infill the quote stays on the estimate, because our slice runs at the profile's sparse default and stops representing what you asked for.

Rounding and the minimum#

  • Billable weight rounds UP to the whole gram, like postage. 39.92 g bills as 40 g. Nothing is added before that rounding — the multi-colour purge surcharge the code can model is switched off, so it contributes nothing.
  • $1.00 is the minimum per part. A 3 g PLA keychain works out at $0.36 and bills at $1.00. The floor is applied per unit, so ten of them floor at $10.00 and not $1.00.

Worked example#

A part measuring 60 x 40 x 30 mm, PLA, Standard quality, 20% infill, one unit, shipped in the US. Every step below is arithmetic you can repeat.

  1. 1
    Start from volume

    An uploaded mesh gives its real volume. This example uses the bounding box, which is what the quote API works from: 60 x 40 x 30 mm = 72,000 mm³ = 72 cm³.

    text
    60 x 40 x 30 / 1000 = 72 cm3
  2. 2
    Apply walls and infill

    30% of the volume is solid wall; the remaining 70% is filled to the requested infill.

    text
    72 x (0.30 + 0.70 x 0.20) = 31.68 cm3
  3. 3
    Convert to weight

    Multiply by the density of PLA, 1.26 g/cm³.

    text
    31.68 x 1.26 = 39.92 g
  4. 4
    Round up

    Billable weight is a whole number of grams.

    text
    ceil(39.92) = 40 g
  5. 5
    Apply the rate and the quality factor

    PLA is $0.12/g and Standard quality is 1.00. This is above the $1.00 minimum, so the minimum does not bite.

    text
    40 x 0.12 x 1.00 = $4.80 per part
  6. 6
    Multiply by quantity, then add shipping

    One unit gets no bulk discount, and US shipping is $7.00 flat below $50.

    text
    4.80 x 1 x 1.00 = $4.80
    4.80 + 7.00 = $11.80

You can check that against the quote API, which is public and needs no key.

POST/api/priceNo auth

Quote a bounding box. No authentication, no rate limit, no order is created.

Request body
bboxMmobjectrequired
Bounding box in millimetres as { x, y, z }. Each must be a finite number above 0. The three values are sorted before the build-volume check, so a long thin part that only fits rotated is still accepted.
materialstringoptionaldefault pla
Anything else is rejected with unknown material: <value>.plapetgabsasatpu
qualitystringoptionaldefault standard
Anything else is rejected with unknown quality: <value>.standardpremium
quantitynumberoptionaldefault 1
Rounded, and floored at 1. Bulk tiers are applied from this number.
colorstringoptional
A stock colour name or a hex value. Trimmed to 64 characters, and a value containing anything outside letters, digits, spaces and # ( ) , . _ - is discarded whole and quoted as no preference. Off-palette raises the per-gram rate to the $0.20 floor.
The example above, as a request
curl -X POST https://x3dstudios.com/api/price \
  -H "Content-Type: application/json" \
  -d '{
    "bboxMm": { "x": 60, "y": 40, "z": 30 },
    "material": "pla",
    "quality": "standard",
    "quantity": 1,
    "color": "Black"
  }'
200 response
{
  "filamentChanges": 0,
  "multiColorGrams": 0,
  "multiColorHours": 0,
  "grams": 40,
  "printHours": 1.98,
  "materialCost": 4.8,
  "machineCost": 0,
  "shipping": 7,
  "baseFee": 0,
  "perUnit": 4.8,
  "subtotal": 4.8,
  "total": 11.8,
  "currency": "USD",
  "material": "pla",
  "quality": "standard",
  "quantity": 1,
  "color": "Black",
  "customColor": false,
  "pricePerGram": 0.12
}

This route quotes a box, not a mesh, so it is an upper bound — a real model inside that box weighs less. Upload the file at /print for a quote from the model itself.

Quantity and bulk#

UnitsFactorDiscount
1–41.00none
5–90.955% off
10 or more0.9010% off
Applied to per-part price x quantity, before the $1.00-per-unit floor.
The cart prices each unit on its own
Bulk tiers apply where a quantity is quoted as one job: the quote shown on /print, the direct order path behind its Order button, /api/price, and a quantity sent to POST /api/print/orders. A cart line is re-quoted server-side as a single unit and multiplied by its quantity at checkout, so it does not pick up the bulk factor. For ten or more of one part, order it as one job rather than as a cart line, or ask at /contact.

Multi-colour#

Nothing is added for colour. A model we slice for you is printed as a single-filament plate — multi-colour is not orderable yet — so a model that looks multi-coloured on screen is quoted and charged at exactly the single-colour price. The quote returns filamentChanges: 0, multiColorGrams: 0 and multiColorHours: 0 on every print for that reason.

The surcharge model does exist in the pricing code, switched off behind a flag, ready for the day a four-colour plate can actually be printed: one filament change per layer per extra colour, 84 mm³ purged per change (the flush volume in the Bambu H2S profile), 1.3 minutes per change, purge grams added before rounding and change hours at $1.50/hour. None of it reaches a quote today.

A file you sliced yourself is the one way to buy a multi-colour print now, and it is priced from its own header: the purge and the tool-change hours are already inside its measured grams and hours, so nothing is added on top. Charging it twice would be an overcharge. See /docs/studio/multi-color for how colours are mapped to trays.

Shipping#

DestinationFlat rateFree at
United States$7.00$50.00 subtotal
International$30.00$500.00 subtotal

Shipping is charged once per order, not per part, and appears as its own line at checkout. One caveat if you are reading the quote API: it always returns shipping: 7, because it prices a part and not a basket. The free-shipping thresholds are applied at checkout against the order subtotal.


The other model: reserving a printer by the hour#

These two price lists must never be mixed
Ordering a print at /print buys a finished part at an all-in per-gram rate that already contains the machine time. Reserving a printer at /farm buys machine time directly, and the filament on top of it is charged at a separate raw rate. Quote the all-in $0.12/g against reserved hours and you have billed the machine twice. Every figure below belongs to reservations only, and every figure above belongs to prints only.
Ordering a printReserving a printer
Where/print/farm
What you buyA finished part, shippedTime on a machine you drive yourself
Machine timeIncluded in the per-gram rate$1.50 per hour, or $15.00 per day
FilamentIncluded in the per-gram rateCharged separately, raw, per gram
When you payAt checkoutMetered on release, settled monthly
Card on fileNot requiredRequired before a reservation starts
Reservation lineRate
Machine, hourly$1.50 per hour
Machine, daily$15.00 per day, billed per started day
PLA filament$0.02 per gram
PETG filament$0.025 per gram
ABS filament$0.03 per gram
Filament swap$0.00
Shipping handling, per shipment$3.00 plus postage
Reservation rates only. A material with no entry above is charged at the PLA rate.
  1. You pick a printer that is AVAILABLE and choose hourly (1–24 hours) or daily. A card on file is required — the reservation is refused with 402 and CARD_REQUIRED without one.
  2. Nothing is charged at booking. The reservation starts at $0.00 and accrues.
  3. Releasing it meters the real elapsed time between reserve and release. Hourly bills elapsed hours x $1.50, rounded to the cent; daily bills each started 24-hour block at $15.00.
  4. Filament is billed on what a job actually used, at the raw rate above. A job's machine time is charged from its actual run time whether it finished, failed or was cancelled.
  5. The balance settles on the monthly card charge, run on the 1st. A declined card leaves the balance open and emails you rather than cancelling anything.

The public /farm page does not publish these rates, so this page and /docs/farm/reservations are where they live.