Products / Manufacturing & CAD / REST API
CAD DXF Quote API
Instant laser-cutting quotes from a DXF: exact cut length, pierce count, part area and BOM in one API call. No AI guesses, no zero-length surprises from splines or blocks.
DXF R12 – R2018+ · ASCII & binary → JSON · SVG preview
Try it free with your own file → No sign-up. Your file is never stored.
Live on RapidAPI (free plan) Questions or a format you need? Write to me
- Cut length
- 500.53 mm
- Pierces
- 5
- Parts / holes
- 1 / 4
- Net area
- 9,398.94 mm²
See it work
Pick a sample, or open the last tab and try it with your own file. Every result here is the engine's real output, nothing is mocked or edited.
Rounded corners as polyline bulges, six round holes, and a slot drawn as four loose entities.
mounting-plate.dxf 55678 bytes
svg_preview
Result
- Cut length
- 805.027 mm
- Pierces
- 7
- Parts / holes
- 1 / 6
- Net area
- 14605.313 mm²
- Bounding box
- 160.0 × 100.0 mm
- Closed / open contours
- 7 / 0
JSON response POST /v1/analyze-dxf
{
"api_version": "2.0",
"unit_code": 4,
"unit_name": "Millimeters",
"active_layer_count": 2,
"ignored_disabled_layer_count": 0,
"clamped_z_anomaly_count": 0,
"total_entity_count": 10,
"pierce_count": 7,
"closed_loop_count": 7,
"total_cut_length": 805.0265,
"bounding_box": {
"min_x": 0.0,
"min_y": 0.0,
"max_x": 160.0,
"max_y": 100.0,
"width": 160.0,
"height": 100.0,
"bounding_area": 16000.0
},
"entity_counts_by_type": {
"ARC": 2,
"CIRCLE": 5,
"LINE": 2,
"LWPOLYLINE": 1
},
"layer_summary": {
"0": {
"entity_count": 10,
"cut_length": 805.0265
}
},
"bom_blocks": [],
"mm_per_unit": 1.0,
"open_contour_count": 0,
"part_count": 1,
"hole_count": 6,
"net_area": 14605.3133,
"duplicate_length_removed": 0.0,
"total_cut_length_mm": 805.027,
"net_area_mm2": 14605.313,
"bounding_box_mm": {
"min_x": 0.0,
"min_y": 0.0,
"max_x": 160.0,
"max_y": 100.0,
"width": 160.0,
"height": 100.0,
"bounding_area": 16000.0
},
"ignored_entities": {
"invisible": 0,
"on_disabled_layers": 0,
"filtered_by_layer_option": 0,
"corrupt_coordinates": 0,
"unreadable": 0,
"not_cut_geometry": {}
},
"file_info": {
"dxf_version": "AC1032",
"binary": false,
"repaired": false
},
"warnings": [],
"svg_preview": "<svg …> (shown above)"
}
A doubled line, a text, dimensions, a title frame (excluded with exclude_layers=FRAME) and a 0.5 mm gap.
messy-export.dxf 57412 bytes · ?exclude_layers=FRAME
svg_preview
Result
- Cut length
- 1005.164 mm
- Pierces
- 3
- Parts / holes
- 1 / 1
- Net area
- 22745.003 mm²
- Bounding box
- 200.0 × 120.0 mm
- Closed / open contours
- 2 / 1
- Duplicate length removed
- 100.0 mm
- Excluded by layer filter
- 1
- Ignored DIMENSION
- 1
- Ignored TEXT
- 1
1 contour(s) have open ends: the drawing may have gaps; each open path needs its own pierce.
Removed 100.0 units of duplicate/overlapping lines from the cut length.
JSON response POST /v1/analyze-dxf
{
"api_version": "2.0",
"unit_code": 4,
"unit_name": "Millimeters",
"active_layer_count": 4,
"ignored_disabled_layer_count": 0,
"clamped_z_anomaly_count": 0,
"total_entity_count": 7,
"pierce_count": 3,
"closed_loop_count": 2,
"total_cut_length": 1005.1637,
"bounding_box": {
"min_x": 0.0,
"min_y": 0.0,
"max_x": 200.0,
"max_y": 120.0,
"width": 200.0,
"height": 120.0,
"bounding_area": 24000.0
},
"entity_counts_by_type": {
"CIRCLE": 1,
"LINE": 5,
"LWPOLYLINE": 1
},
"layer_summary": {
"0": {
"entity_count": 7,
"cut_length": 1105.1637
}
},
"bom_blocks": [],
"mm_per_unit": 1.0,
"open_contour_count": 1,
"part_count": 1,
"hole_count": 1,
"net_area": 22745.0025,
"duplicate_length_removed": 100.0,
"total_cut_length_mm": 1005.164,
"net_area_mm2": 22745.003,
"bounding_box_mm": {
"min_x": 0.0,
"min_y": 0.0,
"max_x": 200.0,
"max_y": 120.0,
"width": 200.0,
"height": 120.0,
"bounding_area": 24000.0
},
"ignored_entities": {
"invisible": 0,
"on_disabled_layers": 0,
"filtered_by_layer_option": 1,
"corrupt_coordinates": 0,
"unreadable": 0,
"not_cut_geometry": {
"DIMENSION": 1,
"TEXT": 1
}
},
"file_info": {
"dxf_version": "AC1032",
"binary": false,
"repaired": false
},
"warnings": [
"1 contour(s) have open ends: the drawing may have gaps; each open path needs its own pierce.",
"Removed 100.0 units of duplicate/overlapping lines from the cut length."
],
"svg_preview": "<svg …> (shown above)"
}
A MINSERT array of a bracket block with nested press-in nut blocks and attributes.
nested-sheet.dxf 56328 bytes
svg_preview
Result
- Cut length
- 1403.575 mm
- Pierces
- 18
- Parts / holes
- 6 / 12
- Net area
- 10975.532 mm²
- Bounding box
- 200.0 × 90.0 mm
- Closed / open contours
- 18 / 0
bom_blocks
| Block | Quantity | Layer | Attributes |
|---|---|---|---|
| BRACKET | 6 | 0 | – |
| PEM_NUT_M4 | 12 | 0 | PART = CLS-M4-1 |
JSON response POST /v1/analyze-dxf
{
"api_version": "2.0",
"unit_code": 4,
"unit_name": "Millimeters",
"active_layer_count": 2,
"ignored_disabled_layer_count": 0,
"clamped_z_anomaly_count": 0,
"total_entity_count": 31,
"pierce_count": 18,
"closed_loop_count": 18,
"total_cut_length": 1403.5752,
"bounding_box": {
"min_x": 10.0,
"min_y": 10.0,
"max_x": 210.0,
"max_y": 100.0,
"width": 200.0,
"height": 90.0,
"bounding_area": 18000.0
},
"entity_counts_by_type": {
"CIRCLE": 12,
"INSERT": 13,
"LWPOLYLINE": 6
},
"layer_summary": {
"0": {
"entity_count": 18,
"cut_length": 1403.5752
}
},
"bom_blocks": [
{
"block_name": "BRACKET",
"layer": "0",
"quantity": 6,
"sample_attributes": {}
},
{
"block_name": "PEM_NUT_M4",
"layer": "0",
"quantity": 12,
"sample_attributes": {
"PART": "CLS-M4-1"
}
}
],
"mm_per_unit": 1.0,
"open_contour_count": 0,
"part_count": 6,
"hole_count": 12,
"net_area": 10975.532,
"duplicate_length_removed": 0.0,
"total_cut_length_mm": 1403.575,
"net_area_mm2": 10975.532,
"bounding_box_mm": {
"min_x": 10.0,
"min_y": 10.0,
"max_x": 210.0,
"max_y": 100.0,
"width": 200.0,
"height": 90.0,
"bounding_area": 18000.0
},
"ignored_entities": {
"invisible": 0,
"on_disabled_layers": 0,
"filtered_by_layer_option": 0,
"corrupt_coordinates": 0,
"unreadable": 0,
"not_cut_geometry": {}
},
"file_info": {
"dxf_version": "AC1032",
"binary": false,
"repaired": false
},
"warnings": [],
"svg_preview": "<svg …> (shown above)"
}
The live demo needs JavaScript, which seems to be switched off. The sample tabs show the engine's real output without it.
Free: 3 runs a day, no sign-up. Files that cannot be read do not count.
What it does
-
Exact cut length
Exact formulas for lines, arcs, circles and rounded polylines; ellipses and splines measured on a fine flattening. Duplicate and overlapping lines are counted once.
-
Pierces per contour, not per entity
A rectangle drawn as four separate lines is one pierce. Shared edges for common-line cutting are handled.
-
Parts, holes and net area
Outlines and holes are told apart by nesting (islands inside holes count as parts). Net area is outline minus holes, for material cost and weight.
-
BOM from blocks
Block references, including nested blocks and MINSERT arrays, with quantity, layer and attribute values such as inserts or material tags.
-
Ignores what is not cut
Layers that are off or frozen, invisible entities, text, dimensions and hatches are skipped. Include or exclude layers by name, for example a title-block frame.
-
Warnings you can act on
Open contours (gaps in the drawing) are flagged, and every skipped entity is listed with the reason.
-
Instant quote with your own rates
`POST /v1/quote-dxf` applies the shop's own prices to the drawing: material per m² (bounding box or net area), cutting per metre, per pierce, setup, quantity and a minimum price. The answer is an itemised quote; the API never invents a price.
Specification
- Input
- DXF R12 to R2018+, ASCII and binary, including minimal hand-written or CAM-generated files
- Entities
- LINE, ARC, CIRCLE, ELLIPSE, SPLINE, LWPOLYLINE (with bulges), POLYLINE/VERTEX; nested, scaled, rotated and mirrored blocks; MINSERT arrays
- Returns
- Cut length, pierce count, closed and open contours, parts, holes, net area, bounding box, BOM, per-layer summary, warnings, SVG preview, optional per-contour detail
- Units
- Any drawing unit; every value is also given in millimetres
- Endpoints
POST /v1/analyze-dxf(file upload) ·POST /v1/analyze-dxf-raw(JSON body, text or base64) ·POST /v1/quote-dxf(file upload) ·POST /v1/quote-dxf-raw(JSON body)- Quote parameters
material_price_per_m2,material_area(bounding_boxdefault, ornet),cut_price_per_m,pierce_price,setup_price,quantity(default 1),minimum_price,currency(label, defaultEUR). All optional, default 0.- Limits
- 25 MB per request
- Engine
- Deterministic, no AI. The same drawing always gives the same numbers.
Request and fields
curl -X POST "https://<host>/v1/analyze-dxf?exclude_layers=FRAME,DIMS" -F "file=@part.dxf"
| Field | Meaning |
|---|---|
total_cut_length (+ _mm) |
Length of everything that gets cut |
pierce_count |
One per closed contour, one per open path |
closed_loop_count, open_contour_count |
Closed contours and open paths; open ends trigger a warning |
part_count, hole_count, net_area (+ _mm2) |
Outlines and holes by nesting; outline area minus holes |
bounding_box (+ _mm) |
Extents of the cut geometry only |
bom_blocks |
Block references with quantity, layer and attribute values |
layer_summary, entity_counts_by_type |
Per-layer entity count and cut length; entity types used |
ignored_entities, warnings, file_info |
What was skipped and why; repaired or binary file info |
svg_preview |
Small vector preview of the cut geometry |
contours (optional) |
Each contour’s role, length, area, pierces and bounding box |
Instant quote
curl -X POST "https://<host>/v1/quote-dxf?material_price_per_m2=40&cut_price_per_m=1.2&pierce_price=0.05&setup_price=15&quantity=20&minimum_price=50" -F "file=@part.dxf"
unit price = material (rate × area) + cutting (rate × cut metres) + piercing (rate × pierces)
total = max(minimum price, unit price × quantity + setup price)
The response has quote, with each line’s basis, rate and amount rounded to cents so the lines add up, and the
full analysis from above. Notes warn about open contours (the cut length may be wrong) and drawings with
several parts.
How it was tested
- 14 reference drawings with analytic answers, ASCII and binary. Cut length within 0.02 mm; pierces and bounding box exact.
- Net area within about 0.02 %.
- A 1000 × 500 mm perforated sheet with 2,500 holes: about 4 seconds, 2,501 pierces, cut length exact.
- 3,600 randomly damaged files without a crash. Damaged entities are skipped and reported.
- A 200 × 130 mm SolidWorks sign plate agrees with SolidWorks’ own STL export within 0.5 % (area) and 0.7 % (cut length). The gap comes from the STL’s chord approximation.
Known limits
What it does not do yet, so you can decide before you integrate.
- DWG is not supported. The API answers with a clear message asking for a DXF export.
- Ellipses and splines are measured on a fine flattening rather than an exact formula.
- Files without a unit are read as millimetres, with a warning.
- Kerf compensation and lead-in / lead-out lengths are not included.
Privacy
Drawings are processed in memory and never stored.
Free tools with this engine
DXF cut length calculator
Exact cut length of a DXF for laser, waterjet, plasma or CNC quotes, duplicates counted once.
Count pierces in a DXF
Pierces per contour, not per entity, for laser and plasma quotes. Open contours flagged.