POST /API/V1/CAD/EXTRACT
CAD and drawing extraction
Turn native CAD files and 2D drawings into structured, agent-readable JSON. Upload STEP, IGES, DXF, PDF, SVG, or draw.io and receive four-cad.extraction.v1: solids with topology and mass properties, drawing entities, measured dimensions, annotations, and an optional Rowe-ready point_cloud_scene.
POST /api/v1/cad/extract
Authenticate with your API key, upload a file up to 25 MB, and pick a target_contract: structured (default) for the agent-readable extraction, point_cloud_scene for Rowe-ready geometry, or both. The endpoint accepts multipart uploads and JSON with base64 content.
https://fourechelon.com/api/v1/cad/extractcurl https://fourechelon.com/api/v1/cad/extract \ -H "Authorization: Bearer $FOUR_ECHELON_API_KEY" \ -F "file=@bracket.step" \ -F "target_contract=both"The same request as JSON with base64-encoded content:
$ curl https://fourechelon.com/api/v1/cad/extract \ -H "Authorization: Bearer $FOUR_ECHELON_API_KEY" \ -H "Content-Type: application/json" \ -d "{$ \"file_name\": \"drawing.dxf\",$ \"target_contract\": \"structured\",$ \"content_base64\": \"$(base64 -i drawing.dxf | tr -d '\n')\"$ }"Request bodies are capped at about 6 MB by the hosting platform, so inline uploads (multipart or base64) work up to roughly 4 MB of file. For larger files, up to 25 MB, send a public content_url instead and the server downloads it (http(s) only, 20 s; private and loopback hosts are refused):
$ curl https://fourechelon.com/api/v1/cad/extract \ -H "Authorization: Bearer $FOUR_ECHELON_API_KEY" \ -H "Content-Type: application/json" \ -d '{$ "file_name": "assembly.step",$ "target_contract": "both",$ "content_url": "https://files.example.com/exports/assembly.step"$ }'Response schema
Successful extractions return four-cad.extraction.v1. 3D sources fill structure.solids with topology and mass properties; 2D drawings fill structure.entities and structure.dimensions. Sections that do not apply to the source are omitted.
schemastringAlways four-cad.extraction.v1 for successful extractions.
source_formatstringDetected input format (step, stp, iges, igs, dxf, pdf, svg, drawio).
unitsstringLength unit of the extraction, for example millimeter.
structure.kindstringbrep for 3D solids, drawing2d for DXF/PDF/SVG drawings, diagram2d for draw.io diagrams (pages, nodes, edges, relations, graph).
structure.assembly / structure.solidsarray3D topology: per-solid bbox, volume, surface_area, center_of_mass, face/edge/vertex counts, typed faces (plane, cylinder, ...), and edge_types.
structure.layers / structure.entitiesarray2D drawing content: layers plus typed entities (line, circle, arc, polyline, text, ...) with geometry, layer, and text.
structure.dimensionsarrayMeasured drawing dimensions: dim_type, numeric measurement, display text, and definition points.
structure.annotations / structure.blocks / structure.pagesarrayNotes, reusable block definitions, and page structure when the source has them.
structure.drawing_metadataobjectDXF and PDF drawings: title_block fields (title, drawing_number, revision, material, scale, sheet, drawn_by, ...), bom rows, revisions rows, and numbered notes, each with the source annotation ids and a confidence. Read from the vector text, never OCR. Omitted when the sheet has none.
structure.calloutsarrayDXF/PDF: engineering callouts parsed from dimension and note text — threads (M6x1.0-6H, 1/4-20 UNC-2B), holes with counterbore/countersink/spotface, ±/bilateral tolerances, ISO fits (25 H7), radii, chamfers, surface finish (Ra), reference dimensions — each with quantity, through/depth, the source text id, and position.
point_cloud_sceneobjectRowe-ready point_clouds[] sampled from the geometry. Present when target_contract is point_cloud_scene or both.
statisticsobjectConverter statistics about the parsed file.
warningsarrayNon-fatal parse warnings. Sections that do not apply to the source format are omitted.
usageobjectMetered spatial tokens: input from uploaded bytes, output from the extraction JSON.
request_idstringRequest id for support and debugging.
{ "schema": "four-cad.extraction.v1", "source_format": "dxf", "units": "millimeter", "structure": { "kind": "drawing2d", "layers": ["0", "DIMENSIONS"], "entities": [ { "id": "e1", "type": "line", "layer": "0", "geometry": { "start": [0, 0], "end": [120, 0] } }, { "id": "e2", "type": "circle", "layer": "0", "geometry": { "center": [60, 40], "radius": 8 } } ], "dimensions": [ { "id": "d1", "dim_type": "linear", "measurement": 120.0, "text": "120", "defpoints": [[0, 0], [120, 0]] } ], "annotations": [], "blocks": [] }, "point_cloud_scene": { "point_clouds": [ { "object_id": "drawing", "kind": "surface", "points": [{ "x": 0, "y": 0, "z": 0 }] } ] }, "statistics": { "entity_count": 2, "dimension_count": 1 }, "warnings": [], "file_name": "drawing.dxf", "target_contract": "both", "usage": { "input_tokens": 20890, "output_tokens": 512, "estimated_input_cost_usd": 0.02089, "estimated_output_cost_usd": 0.002048, "estimated_cost_usd": 0.022938 }, "request_id": "req_..."}Supported formats
step / stp3D CADISO 10303 STEP solids and assemblies. Preferred 3D input.
iges / igs3D CADIGES solids and surfaces.
dxf2D drawingAutoCAD DXF: layers, entities, dimensions, blocks, annotations.
pdf2D drawingVector PDF drawings parsed into pages and entities.
svg2D drawingSVG vector drawings parsed into entities.
drawio / xmlDiagramdraw.io diagrams: nodes with absolute bounding boxes, containers, directed connectors, labels, spatial relations, and a graph summary. Compressed and multi-page files are handled.
png / svg (draw.io export)DiagramA draw.io PNG or SVG exported with 'Include a copy of my diagram' carries the diagram; it is read as diagram2d, not traced. A PNG without one is a 422.
sldprt / sldasmrejected (415)SolidWorks native files are not parsed. Export as STEP and upload the .step file.
Errors and pricing
Extraction is metered like every Rowe request: uploaded bytes count as input spatial tokens and the extraction JSON counts as output spatial tokens at the standard token rates. Only 2xx extractions are billed; converter and validation failures are recorded but never charged.
400invalid_request_errorMissing file/file_name, invalid base64 content, or invalid target_contract.
401authentication_errorMissing, revoked, or invalid API key.
402payment_requiredAn active or trialing paid API subscription is required.
413request_too_largeThe request body is over the ~6 MB platform limit (inline base64 or multipart), or the file is over 25 MB. Files above ~4 MB: send content_url instead of content_base64; the server downloads it (public http(s) only, 20 s).
415unsupported_file_typeFormat outside STEP/STP/IGES/IGS/DXF/PDF/SVG/DRAWIO/XML, including SolidWorks files (export STEP).
422converter error (passed through)The converter parsed the request but could not extract the file; its error body is returned unchanged.
502/503converter_unavailableNo converter is configured or the converter cannot be reached. Non-2xx responses are never billed.
Batch extraction: POST /api/v1/cad/extract/batch
Submit 1-32 files in one request (25 MB per file, 25 MB total) and get a 202 Accepted with a batch id. Extraction runs in the background; poll status_url until status is done or failed. Each item is authorized, extracted, and metered exactly like one call to /api/v1/cad/extract: same converter, same token counts, same 2xx-only billing, and at most 5 batches queued or running per key.
https://fourechelon.com/api/v1/cad/extract/batch$ curl https://fourechelon.com/api/v1/cad/extract/batch \ -H "Authorization: Bearer $FOUR_ECHELON_API_KEY" \ -F "files=@bracket.step" \ -F "files=@plate.dxf" \ -F "files=@housing.step" \ -F "target_contract=both" $ # Poll until status is done or failed$ curl https://fourechelon.com/api/v1/cad/extract/batch/cb_0123456789abcdef01234567 \ -H "Authorization: Bearer $FOUR_ECHELON_API_KEY"The 202 response:
HTTP/1.1 202 AcceptedLocation: https://fourechelon.com/api/v1/cad/extract/batch/cb_0123456789abcdef01234567
{ "object": "cad_extract_batch", "id": "cb_0123456789abcdef01234567", "status": "queued", "item_count": 3, "counts": { "queued": 3, "running": 0, "succeeded": 0, "failed": 0 }, "usage": { "input_tokens": 0, "output_tokens": 0, "estimated_cost_usd": 0 }, "status_url": "https://fourechelon.com/api/v1/cad/extract/batch/cb_0123456789abcdef01234567", "created_at": "2026-09-02T18:04:11.000Z", "started_at": null, "completed_at": null, "expires_at": "2026-09-03T18:04:11.000Z", "items": [ { "index": 0, "file_name": "bracket.step", "source_format": "step", "target_contract": "both", "status": "queued", "status_code": null, "request_id": null, "attempts": 0, "result": null, "result_url": null, "result_bytes": null, "error": null, "usage": null, "started_at": null, "completed_at": null }, { "index": 1, "file_name": "plate.dxf", "source_format": "dxf", "target_contract": "both", "status": "queued", "status_code": null, "request_id": null, "attempts": 0, "result": null, "result_url": null, "result_bytes": null, "error": null, "usage": null, "started_at": null, "completed_at": null }, { "index": 2, "file_name": "housing.step", "source_format": "step", "target_contract": "both", "status": "queued", "status_code": null, "request_id": null, "attempts": 0, "result": null, "result_url": null, "result_bytes": null, "error": null, "usage": null, "started_at": null, "completed_at": null } ], "request_id": "req_..."}Batch status: GET /api/v1/cad/extract/batch/{id}
Returns the aggregate status plus every item in submission order. Small results are inline under result; results over 128 KB are served from result_url instead, which is an authenticated GET on the same key (no public storage links). Results are kept until expires_at (24 hours).
files / itemsmultipart or array1-32 files. Multipart: repeat the `files` part (shared `target_contract` field). JSON: `items[]` of `{ file_name, content_base64, target_contract? }`, the array form of the single endpoint's body.
objectstringThe batch envelope is cad_extract_batch.
idstringBatch id (cb_...). Poll `status_url`, or GET /api/v1/cad/extract/batch/{id}, with any key on the same account.
statusstringqueued → running → done (at least one item succeeded) or failed (every item failed). expired after `expires_at`.
countsobjectPer-status item counts: queued, running, succeeded, failed.
items[].statusstringqueued, running, succeeded, or failed. Converter 5xx and transport failures are retried up to 3 times with backoff; converter 4xx fails the item immediately.
items[].result / result_urlobject or stringThe four-cad.extraction.v1 body (identical to the single endpoint) inline up to 128 KB; larger extractions set `result_url` to GET /api/v1/cad/extract/batch/{id}/items/{index}/result, which streams the stored body with the same API key.
items[].usageobjectMetered exactly like one POST /api/v1/cad/extract call: input from uploaded bytes, output from the extraction JSON. Only 2xx items are billed; failed items report usage but are not charged; retries never charge twice. The batch envelope itself is free.
usageobjectBilled totals across succeeded items (input_tokens, output_tokens, estimated_cost_usd).
expires_atstringResults and staged files are deleted 24 hours after submission.
Idempotency-KeyheaderOptional. Resubmitting the same files with the same key returns the original batch (Idempotency-Replayed: true); different files return 409.
{ "object": "cad_extract_batch", "id": "cb_0123456789abcdef01234567", "status": "done", "item_count": 3, "counts": { "queued": 0, "running": 0, "succeeded": 2, "failed": 1 }, "usage": { "input_tokens": 31204, "output_tokens": 1810, "estimated_cost_usd": 0.19222 }, "status_url": "https://fourechelon.com/api/v1/cad/extract/batch/cb_0123456789abcdef01234567", "created_at": "2026-09-02T18:04:11.000Z", "started_at": "2026-09-02T18:04:12.000Z", "completed_at": "2026-09-02T18:04:39.000Z", "expires_at": "2026-09-03T18:04:11.000Z", "items": [ { "index": 0, "file_name": "bracket.step", "source_format": "step", "target_contract": "both", "status": "succeeded", "status_code": 200, "request_id": "req_item0...", "attempts": 1, "result": { "schema": "four-cad.extraction.v1", "source_format": "step", "units": "millimeter", "structure": { "kind": "brep", "solids": [{ "id": "s1", "volume": 1350.2 }] }, "point_cloud_scene": { "point_clouds": [{ "object_id": "s1", "kind": "surface", "points": [{ "x": 0, "y": 0, "z": 0 }] }] }, "statistics": { "solid_count": 1 }, "warnings": [], "file_name": "bracket.step", "target_contract": "both", "usage": { "input_tokens": 20890, "output_tokens": 1298, "estimated_input_cost_usd": 0.10445, "estimated_output_cost_usd": 0.02596, "estimated_cost_usd": 0.13041 }, "request_id": "req_item0..." }, "result_url": null, "result_bytes": 4812, "error": null, "usage": { "input_tokens": 20890, "output_tokens": 1298, "estimated_cost_usd": 0.13041 }, "started_at": "2026-09-02T18:04:12.000Z", "completed_at": "2026-09-02T18:04:21.000Z" }, { "index": 1, "file_name": "plate.dxf", "source_format": "dxf", "target_contract": "both", "status": "succeeded", "status_code": 200, "request_id": "req_item1...", "attempts": 1, "result": null, "result_url": "https://fourechelon.com/api/v1/cad/extract/batch/cb_0123456789abcdef01234567/items/1/result", "result_bytes": 913442, "error": null, "usage": { "input_tokens": 10314, "output_tokens": 512, "estimated_cost_usd": 0.06181 }, "started_at": "2026-09-02T18:04:12.000Z", "completed_at": "2026-09-02T18:04:30.000Z" }, { "index": 2, "file_name": "housing.step", "source_format": "step", "target_contract": "both", "status": "failed", "status_code": 422, "request_id": "req_item2...", "attempts": 1, "result": { "error": { "message": "STEP entity graph is truncated.", "type": "extraction_error" }, "file_name": "housing.step", "target_contract": "both", "request_id": "req_item2...", "usage": { "input_tokens": 15020, "output_tokens": 43, "estimated_input_cost_usd": 0.0751, "estimated_output_cost_usd": 0.00086, "estimated_cost_usd": 0.07596 } }, "result_url": null, "result_bytes": 268, "error": { "message": "STEP entity graph is truncated.", "type": "extraction_error" }, "usage": { "input_tokens": 15020, "output_tokens": 43, "estimated_cost_usd": 0.07596 }, "started_at": "2026-09-02T18:04:21.000Z", "completed_at": "2026-09-02T18:04:39.000Z" } ], "request_id": "req_..."}Batch-specific errors (per-file validation errors match the single endpoint and reject the whole batch before anything is staged):
400invalid_request_errorNo files, more than 32, bad base64, or an invalid target_contract. `details` names the offending item index and file_name.
413request_too_largeA single file over 25 MB, the batch total over 25 MB, or the request body over the ~6 MB platform limit. `details` reports limit_bytes and received_bytes.
415unsupported_file_typeAny item outside STEP/STP/IGES/IGS/DXF/PDF/SVG/DRAWIO/XML rejects the whole batch before anything is staged or charged.
429rate_limit_exceededMore than 5 batches queued or running, or more than 10 submitted in a minute, on one key. Per-item token charges are unaffected.
404not_foundGET with an id that does not exist or belongs to another account.