TetriCut API

Parse engineering files. Optimize material cutting. Export CNC-ready output.

BASE URL https://api.tetricut.com/v1

Quickstart

1. Get an API Key

curl -X POST https://api.tetricut.com/v1/account/register \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com", "name":"Your Name", "password":"secret"}'

Save the api_key from the response. It's shown only once.

2. Parse a DXF File

curl -X POST https://api.tetricut.com/v1/parse/dxf \
  -H "X-API-Key: na_live_YOUR_KEY" \
  -F "file=@your_part.dxf"

3. Optimize a Cutting Plan

curl -X POST https://api.tetricut.com/v1/solve/cut-1d \
  -H "X-API-Key: na_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "stocks": [{"id": "6m-bar", "length": 6000, "quantity": 20, "cost": 25}],
    "pieces": [
      {"id": "piece-A", "length": 2500, "quantity": 8},
      {"id": "piece-B", "length": 1200, "quantity": 15}
    ],
    "kerf": 3
  }'

Authentication

Pass your API key via the X-API-Key header or ?api_key= query parameter.

Parse Endpoints

POST /v1/parse/dxf
Upload a DXF file, get structured JSON geometry. Extracts polygons, holes, cut paths, bend lines, layers, and dimensions. Supports ASCII and binary DXF with auto unit conversion.

Request

ParamTypeDescription
filemultipart/form-dataDXF file (max 10MB)

Response

{
  "status": "success",
  "data": {
    "name": "bracket",
    "bounds": {"min_x": 0, "min_y": 0, "max_x": 150.5, "max_y": 200.3},
    "dimensions": {"width": 150.5, "height": 200.3, "unit": "mm"},
    "area": 12500.75,
    "perimeter": 680.2,
    "geometry": {
      "exterior": [[0,0], [150.5,0], [150.5,200.3], [0,200.3], [0,0]],
      "holes": [[[50,50], [60,50], [60,60], [50,60], [50,50]]]
    },
    "layers": ["0", "OUTER", "HOLES"],
    "cut_paths": [...],
    "bend_lines": null,
    "entity_count": 12,
    "has_holes": true,
    "hole_count": 1
  },
  "meta": {"processing_time_ms": 45, "engine_version": "1.0.0"}
}

POST /v1/parse/dxf-to-svg
Upload a DXF file, get an SVG string back. Configurable output size, stroke color, and background.

Request

ParamTypeDescription
filemultipart/form-dataDXF file
widthquery intSVG width in px (default: 800)
heightquery intSVG height in px (default: 600)
stroke_colorquery stringHex color (default: #000000)
backgroundquery stringBackground color (default: #ffffff)

Solve Endpoints

POST /v1/solve/nest-2d
Optimize 2D part placement on rectangular sheets. Minimizes material waste. Supports polygons with holes, rotation, multi-sheet output.

Request

{
  "parts": [
    {
      "id": "bracket",
      "exterior": [[0,0],[150,0],[150,80],[0,80],[0,0]],
      "holes": [[[40,20],[110,20],[110,60],[40,60],[40,20]]],
      "quantity": 10
    },
    {
      "id": "plate",
      "exterior": [[0,0],[200,0],[200,200],[0,200],[0,0]],
      "quantity": 4
    }
  ],
  "sheet": {"width": 1220, "height": 2440},
  "config": {
    "spacing": 3.0,
    "edge_margin": 5.0,
    "rotation_step": 90,
    "kerf": 0.2
  }
}

Parameters

FieldTypeDescription
parts[].idstringUnique part identifier
parts[].exteriorfloat[][]Closed polygon coordinates [[x,y], ...]
parts[].holesfloat[][][]Optional holes in the polygon
parts[].quantityintNumber of copies to nest
sheet.widthfloatSheet width in mm
sheet.heightfloatSheet height in mm
config.spacingfloatGap between parts (default: 3mm)
config.kerffloatTool cutting width (default: 0)
config.rotation_stepfloatRotation angles: 90 = 0/90 only, 45 = 0/45/90

Response

{
  "status": "success",
  "data": {
    "summary": {
      "sheets_used": 2,
      "total_parts": 14,
      "placed_parts": 14,
      "unplaced_parts": 0,
      "total_utilization": 68.5,
      "total_waste_percent": 31.5
    },
    "sheets": [{
      "index": 0,
      "utilization": 72.3,
      "placements": [{
        "part_id": "bracket",
        "instance": 0,
        "x": 5.0, "y": 5.0,
        "rotation": 0,
        "bounds": {"min_x": 5, "min_y": 5, "max_x": 155, "max_y": 85}
      }]
    }],
    "unplaced": []
  },
  "meta": {"processing_time_ms": 1200, "engine_version": "1.0.0"}
}

POST /v1/solve/cut-1d
Optimize cutting pieces from stock lengths. Minimize waste or cost using First Fit Decreasing with consolidation. Supports multiple stock sizes and blade kerf.

Request

{
  "stocks": [
    {"id": "6m-bar", "length": 6000, "quantity": 50, "cost": 25.00},
    {"id": "3m-bar", "length": 3000, "quantity": 100, "cost": 14.00}
  ],
  "pieces": [
    {"id": "long-piece", "length": 2500, "quantity": 8},
    {"id": "medium", "length": 1200, "quantity": 15},
    {"id": "short", "length": 800, "quantity": 24}
  ],
  "kerf": 3,
  "optimize": "waste"
}

Parameters

FieldTypeDescription
stocks[].idstringStock identifier
stocks[].lengthfloatStock length in mm
stocks[].quantityintAvailable quantity
stocks[].costfloatCost per stock unit
pieces[].idstringPiece identifier
pieces[].lengthfloatRequired piece length
pieces[].quantityintNumber needed
kerffloatBlade/saw width per cut (default: 0)
optimizestring"waste" or "cost"

Response

{
  "status": "success",
  "data": {
    "summary": {
      "stocks_used": 11,
      "total_stock_length": 66000,
      "total_cut_length": 57100,
      "total_waste": 8900,
      "waste_percent": 13.3,
      "total_cost": 275.00,
      "all_pieces_placed": true
    },
    "layouts": [{
      "stock_id": "6m-bar",
      "stock_index": 0,
      "cuts": [
        {"piece_id": "long-piece", "length": 2500, "position": 0},
        {"piece_id": "long-piece", "length": 2500, "position": 2503},
        {"piece_id": "short", "length": 800, "position": 5006}
      ],
      "used_length": 5806,
      "waste": 194,
      "utilization": 96.8
    }],
    "unplaced": []
  },
  "meta": {"processing_time_ms": 2, "engine_version": "1.0.0"}
}

Export Endpoints

POST /v1/export/gcode
Generate CNC G-code from nesting placements. Returns a downloadable .gcode file.
POST /v1/export/dxf
Generate a DXF file from nesting placements with sheet boundary and kerf compensation.

Request (both endpoints)

{
  "sheet_width": 1220,
  "sheet_height": 2440,
  "placements": [
    {
      "exterior": [[5,5],[155,5],[155,85],[5,85],[5,5]],
      "holes": [],
      "x": 5, "y": 5, "rotation": 0
    }
  ],
  "config": {
    "feed_rate": 1000,
    "travel_rate": 3000,
    "laser_power": 100,
    "kerf": 0.2
  }
}

Error Handling

All errors follow this format:

{
  "detail": {
    "code": "ERROR_CODE",
    "message": "Human-readable description"
  }
}
CodeHTTPMeaning
AUTH_REQUIRED401No API key provided
INVALID_API_KEY401Key is invalid or revoked
RATE_LIMIT_EXCEEDED429Too many requests per minute
USAGE_LIMIT_EXCEEDED402Monthly quota reached
INVALID_DXF400File is not valid DXF
INVALID_INPUT400Bad request data
FILE_TOO_LARGE413File exceeds 10MB

Rate Limit Headers

Every response includes:

HeaderDescription
X-RateLimit-LimitRequests allowed per minute
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when limit resets

SDKs & Libraries

Coming soon: Python, JavaScript, and Go client libraries.

For now, use any HTTP client. The API accepts standard JSON and multipart/form-data.

TetriCut API by tetricut.com

Swagger UI | Redoc | OpenAPI Spec