Quoting API
Quoting API
The pipeline that powers the public quote tool, exposed as plain HTTP. Convert a STEP into geometry data, fetch material + finishing options, compute a shell-pricing quote, and (if you want) place the order — all behind one X-API-Key header.
Pipeline at a glance
GET /materials— pick a material UUID for your part.POST /convert— upload the STEP/glTF, receive volume / surface area / bbox + a base64 GLB for preview.- (Optional)
GET /post-processing— pick finishing services. POST /quotes— provide geometry + material + quantity, receive a full pricing breakdown.GET /quotes/:id— later, retrieve the same quote for follow-up.
/convert
Upload a STEP / STP / glTF / GLB file. KittyCAD extracts volume, surface area, axis-aligned bounding box, and produces a renderable GLB. 25 MB file cap, 60-second timeout. Response is plain JSON; no async polling needed.
Request
curl -X POST https://digitalmetal.io/api/v1/convert \
-H "X-API-Key: dm_live_<your_key>" \
-F "file=@bracket.step"Response 200
{
"geometry": {
"volume_cm3": 12.4503,
"surface_area_cm2": 84.2011,
"bounding_box": { "x_mm": 48.300, "y_mm": 32.100, "z_mm": 21.600 }
},
"glb_base64": "<base64-encoded GLB binary>"
}Common errors
400— missing or invalid file field413— file exceeds 25 MB422— multi-body file (split + upload separately) / part exceeds 150 mm build volume / geometry not extractable
/materials
Active casting materials. Use the returned UUID as material_id when creating a quote.
Response 200
{
"materials": [
{
"id": "uuid",
"name": "Aluminum A356",
"description": "General-purpose casting alloy",
"density_kg_m3": 2680,
"cost_per_kg": 4.20,
"maximum_part_size_mm": "150mm x 150mm x 150mm"
}
]
}/post-processing
Active post-processing / finishing options. Each option carries pricing model + unit cost.
Response 200
{
"post_processing_options": [
{
"id": "uuid",
"name": "Bead blast",
"description": "Uniform satin finish",
"pricing_model": "per_part",
"cost_per_unit": 4.50
}
]
}/quotes
Generates a shell-pricing quote and persists it to your account. Geometry comes from /convert, the material UUID from /materials.
Request body (application/json)
{
"file_name": "bracket.step",
"geometry": { "volume_cm3": 12.45, "surface_area_cm2": 84.2,
"bounding_box": { "x_mm": 48.3, "y_mm": 32.1, "z_mm": 21.6 } },
"material_id": "<uuid>",
"quantity": 10,
"post_processing_option_ids": ["<uuid>", "..."] // optional
}Response 200
{
"quote": {
"id": "uuid",
"status": "draft",
"unit_price": 18.42,
"total_price": 184.20,
"breakdown": {
"metal_cost": 3.10,
"shell_cost": 5.40,
"labor_cost": 4.20,
"post_processing_cost": 4.50,
"margin": 1.22
},
"lead_time_days": 14
}
}/quotes/:id
Retrieve a previously created quote. Response shape matches POST /quotes.
curl https://digitalmetal.io/api/v1/quotes/a1b2c3d4-... \
-H "X-API-Key: dm_live_<your_key>"End-to-end example
Convert → pick a material → price 10 parts:
# 1. extract geometry
curl -sS -X POST https://digitalmetal.io/api/v1/convert \
-H "X-API-Key: $DM_KEY" -F "file=@bracket.step" > geom.json
# 2. pick the first material
curl -sS https://digitalmetal.io/api/v1/materials \
-H "X-API-Key: $DM_KEY" | jq '.materials[0].id' > matid
# 3. quote
jq -n \
--slurpfile g geom.json \
--rawfile m matid \
'{ file_name: "bracket.step", geometry: $g[0].geometry,
material_id: ($m | rtrimstr("\n") | gsub("\""; "")), quantity: 10 }' \
| curl -sS -X POST https://digitalmetal.io/api/v1/quotes \
-H "X-API-Key: $DM_KEY" -H "Content-Type: application/json" -d @-