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.