The upload capability exposes two endpoints. Both take the
file as the raw request body (application/octet-stream) with the filename
in an X-Filename header, and return 202 Accepted immediately — the import
runs asynchronously.
| Endpoint | Behavior |
|---|---|
POST /api/file/upload |
Imports the file into the current project (merge). Supports placement headers. |
POST /api/file/open |
Replaces the current project with the file (File → Open). No placement headers. |
import urllib.request
data = open("design.svg", "rb").read()
req = urllib.request.Request(
"http://localhost:19520/api/file/upload",
data=data,
method="POST",
headers={
"Authorization": f"Bearer {bearer_token(secret)}",
"Content-Type": "application/octet-stream",
"X-Filename": "design.svg",
},
)
print(urllib.request.urlopen(req).read()) # {"status": "accepted", ...}The X-Filename extension selects the loader/translator, so set it to match the
payload (.svg, .dxf, .lbrn2, …).
By default the import lands at the current view center. To anchor it at a specific workspace coordinate:
| Header | Meaning |
|---|---|
X-Position-X, X-Position-Y |
Anchor point in workspace mm (workpiece origin). Must be sent as a pair. |
X-Origin |
Which corner of the import's bounding box sits at the anchor: top-left … bottom-right, or center (default). Ignored unless both position headers are present. |
X-Group-Shapes |
"true" keeps imported shapes grouped; "false" (default) uses the app's global grouping preference. |
The 202 only means the file was received. The actual import result arrives
over the state channel as a file_imported event, carrying
{"success": true} or {"success": false, "error": "…"}. Request the state
capability too if you need to confirm the import.
This event is only delivered on the GET /api/events SSE stream. The
GET /api/events/poll fallback returns a snapshot of current state — position,
job, overrides, aux, connection, settings — and does not carry events, so a
polling client cannot observe file_imported. If you need import confirmation,
hold an SSE connection open across the upload.
See openapi.yaml for the full header and response schemas.