API reference

Unfold from your own pipeline.

POST a STEP part, get back a cut-ready flat pattern — the same engine the app runs. One authenticated request returns the geometry and bend schedule, and optionally the DXF (or dimensioned PDF / bend-table CSV). The API is included on the Starter plan and above.

Authentication

Every request carries an API key. Create one in the app under Plans & credits → API keys; the full secret (blk_…) is shown once at creation — store it somewhere safe, because it can't be retrieved again. Revoke a key any time from the same panel.

Send the key as a bearer token (or the X-API-Key header):

Authorization: Bearer blk_your_key_here
Treat a key like a password — it can spend your download allowance and credits. Keep it server-side; never ship it in a browser or mobile app. The endpoint for your account is shown in the app's API-keys panel.

Endpoint

POST{your-api-base}/api-unfold

The request is multipart/form-data (a file plus a few fields). The exact base URL for your account is shown in the app's API-keys panel.

Request fields

FieldTypeRequiredDescription
stepfileyesThe STEP/STP part to unfold.
thickness_mmnumberyesMaterial thickness in millimetres (> 0).
k_factornumberyesNeutral-axis K-factor, between 0 and 1.
downloadstringnoOmit for a free unfold (geometry only). Set to dxf, pdf, or csv to also return that file — this spends one download unit.
base_faceJSON stringnoOverride the base face, as a geometric locator: {"centroid":[x,y,z],"normal":[x,y,z]}. Falls back to the largest planar face with a warning.

What's free, what's metered

Unfolding is always free — a request without download returns the flat geometry, bend schedule, and any warnings, and costs nothing. You only spend a unit when you ask for a file. One download = one unit (allowance first, then a credit), whatever the format — exactly like the app. A failed unfold never costs anything.

downloadReturns a file?CostPlan needed
(omitted)No — geometry onlyFreeStarter+
dxfDXF (CUT + BEND layers)1 unitStarter+
pdfDimensioned PDF drawing1 unitStarter+
csvPress-brake bend-table CSV1 unitPro+

Response

A 200 is always JSON. The file, when requested, arrives base64-encoded inside it:

{
  "unfold_id": "…",
  "status": "done",
  "flat_geometry": { "outline": [...], "holes": [...], "bend_lines": [...] },
  "bend_metadata": { "bends": [ { "angle_deg": 90, "direction": "up", "radius_mm": 1.5, "length_mm": 120 } ] },
  "warnings": [],
  "diagnostics": { "unfolder": "v2", "defeatured": false },
  "charged": "allowance",
  "file": {
    "format": "dxf",
    "filename": "bracket.dxf",
    "content_type": "application/dxf",
    "base64": "MAo…"
  }
}

file and charged appear only when you request a download. bend_metadata is present for parts the V2 unfolder recovered bends from.

Rate limit

60 requests per minute per key. Over that returns 429; retry after the next minute.

Errors

Errors are JSON with an error code and a human message.

StatuserrorMeaning
400step_required / thickness_required / k_factor_requiredMissing or invalid input.
401invalid_api_keyMissing, unknown, or revoked key.
402no_downloadsOut of allowance and credits. The geometry is still returned; no file.
403plan_requiredYour plan doesn't include the API, or that download format.
410unfold_expiredThe unfold expired before the file could be fetched. Not charged.
422cannot_unfoldThe part couldn't be unfolded (not sheet metal, thickness mismatch, …). Not charged.
429rate_limitedOver 60 requests/minute.
503unfold_unavailableThe engine is temporarily unavailable. Not charged — retry.

Examples

Free unfold — geometry & bend schedule only

curl -X POST "$BENDLINE_API/api-unfold" \
  -H "Authorization: Bearer $BENDLINE_KEY" \
  -F step=@bracket.step \
  -F thickness_mm=2 \
  -F k_factor=0.38

Unfold and download the DXF (spends one unit)

curl -sX POST "$BENDLINE_API/api-unfold" \
  -H "Authorization: Bearer $BENDLINE_KEY" \
  -F step=@bracket.step -F thickness_mm=2 -F k_factor=0.38 \
  -F download=dxf \
| jq -r '.file.base64' | base64 -d > bracket.dxf

Python

import base64, requests

r = requests.post(
    f"{BENDLINE_API}/api-unfold",
    headers={"Authorization": f"Bearer {BENDLINE_KEY}"},
    files={"step": open("bracket.step", "rb")},
    data={"thickness_mm": 2, "k_factor": 0.38, "download": "dxf"},
)
r.raise_for_status()
body = r.json()
print(body["warnings"], body["charged"])
with open("bracket.dxf", "wb") as f:
    f.write(base64.b64decode(body["file"]["base64"]))