Kolos Hetyéssy Software developer

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

Worked example hand-calculated
A 120 by 80 millimetre plate with four 8 millimetre holes near the corners. Five pierce points are numbered. 120 80 1 2 3 4 5 4 × Ø8
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

BlockQuantityLayerAttributes
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.

What it does

  1. 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.

  2. Pierces per contour, not per entity

    A rectangle drawn as four separate lines is one pierce. Shared edges for common-line cutting are handled.

  3. 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.

  4. BOM from blocks

    Block references, including nested blocks and MINSERT arrays, with quantity, layer and attribute values such as inserts or material tags.

  5. 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.

  6. Warnings you can act on

    Open contours (gaps in the drawing) are flagged, and every skipped entity is listed with the reason.

  7. 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_box default, or net), cut_price_per_m, pierce_price, setup_price, quantity (default 1), minimum_price, currency (label, default EUR). 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.

Read the full privacy notice →

Free tools with this engine

Free toolCAD DXF Quote API

DXF cut length calculator

Exact cut length of a DXF for laser, waterjet, plasma or CNC quotes, duplicates counted once.

Free toolCAD DXF Quote API

Count pierces in a DXF

Pierces per contour, not per entity, for laser and plasma quotes. Open contours flagged.