Print from code
Beta. The same API the site uses. No key needed yet; routes may change.
Quote
POST /api/quote with the model as multipart field file. STL, 3MF or STEP, up to 100 MB.
curl -F file=@bracket.stl https://mandarin3d.com/api/quote{
"id": "Xk3…",
"filename": "bracket.stl",
"grams": 6.19,
"seconds": 763.58,
"bbox": [30, 30, 20],
"cached": false,
"example": { "qty": 1, "print": 3.91, "shipping": 5.51, "total": 9.42 }
}Same file again: served from cache in milliseconds. Raw bytes work too: ?filename=part.stl.
Quote in two steps
For a page that should move on before slicing is done (what mandarin3d.com does). Reserve an id, send the file, then read the quote.
# 1. Reserve a quote id (no file yet)
curl https://mandarin3d.com/api/quote/start -H 'content-type: application/json' \
-d '{"filename":"bracket.stl","bytes":22484}'
{ "id": "Xk3…", "url": "/quote/Xk3…" }
# 2. Send the raw file; answers with the quote once it's sliced
curl -X PUT --data-binary @bracket.stl https://mandarin3d.com/api/quote/Xk3…
# 3. Or poll until it's ready
curl https://mandarin3d.com/api/quote/Xk3…
202 { "status": "waiting" | "slicing" | "error", "error": "…" }
200 { "id": "Xk3…", "grams": 6.19, … }An id waits 30 minutes for its file. Same limits as one-step quotes.
Price
POST /api/price for another quantity. No side effects.
curl https://mandarin3d.com/api/price -H 'content-type: application/json' \
-d '{"quoteId":"Xk3…","qty":10}'Or price locally: GET /api/config has the formula, colors and shipping table.
Order
POST /api/checkout returns a checkout link. Send acceptTerms: true only after the buyer accepts: custom made to order, all sales final (Terms).
curl https://mandarin3d.com/api/checkout -H 'content-type: application/json' \
-d '{"quoteId":"Xk3…","color":"BLK","qty":1,"acceptTerms":true}'{ "checkoutId": "co_…", "invoiceUrl": "https://…", "price": { "total": 9.42 } }Options (per order, optional): rush (+50% of the print price, printed within 1 business day), fileCheck (+$5), cleanup (+$5), and extraColors (+$3 each, up to 3 codes) with a colorNote saying which parts get which color. POST /api/price takes the same object.
curl https://mandarin3d.com/api/checkout -H 'content-type: application/json' \
-d '{"quoteId":"Xk3…","color":"BLK","qty":1,"acceptTerms":true,
"options":{"rush":true,"extraColors":["RED"],"colorNote":"lid in red"}}'The buyer pays at invoiceUrl. Ships by USPS in 3-5 days.
Reference
GET /api/config- formula, options, colors, shipping, limits
POST /api/quote- file → grams, time, size, price
POST /api/quote/start- reserve a quote id
PUT /api/quote/:id- file for that id → the quote
GET /api/quote/:id- a saved quote, or 202 while slicing
GET /api/quote/:id/model- mesh for previews
POST /api/price- price for a quantity and options
POST /api/checkout- checkout link
Errors are { "error": "…" } with a plain-English message. Limits: 250 × 250 × 250 mm, 60 quotes per 10 minutes per IP. Questions: orders@mandarin3d.com.