Visualization¶
Take a 3D look at the full CAM tree: setups, blocks, operations, toolpaths, workpiece, and stock. The public API does not ship its own viewer; instead it lets you download a project's CAM job, view it interactively at app.autonomiq.de, and (optionally) upload an edited copy back.
Concepts¶
| Term | What it is |
|---|---|
| CAM job | The full machining tree for a project: setups → blocks → operations, plus the workpiece, stock, machine XML, and per-operation toolpaths. Stored in MongoDB in the FAMC (data-oriented) format. |
| FAMC blob | The binary serialisation of a CAM job. Self-contained: includes references to BOSS-stored meshes and toolpaths so a recipient can render the whole tree without further API calls. |
| Job ID | Each save creates a new MongoDB document with a fresh job_id; the project's current_job_id always points at the latest. Downloading captures the current snapshot at the time of the request. |
| SimplyMill UI | The SvelteKit web app at app.autonomiq.de. It renders the project tree in the left pane and Three.js meshes / toolpaths in the canvas. Logging in with the same user the API key is bound to surfaces the project automatically. |
Endpoints¶
| Method | Path | Scope |
|---|---|---|
GET |
/projects/{project_id}/job |
projects:read |
POST |
/projects/{project_id}/job |
cam:write |
The GET returns the FAMC blob as application/octet-stream with Content-Disposition: attachment; filename="<project_id>_<job_id>.famc". Accept-Encoding: gzip is honoured.
The POST is multipart with one file part (the FAMC blob). It writes a new MongoDB document, advances the project's current_job_id, and returns the new job_id. The previous job is preserved (it falls onto the project's undo stack).
The full request/response schemas live in the Scalar reference.
View a project in the SimplyMill UI¶
If the API key is bound to the same user that logs into the SvelteKit UI (the default, since keys are per-user), no download is needed. Just open the project page:
The UI fetches the current job over the internal API and renders the full tree + meshes. Use this for routine inspection.
Flow: archive a job offline¶
Useful for backups, ticket attachments, or reproducing an old run later.
import requests
API = "https://app.autonomiq.de/backend-api/api/public/v1"
H = {"X-API-Key": "smk_live_..."}
resp = requests.get(
f"{API}/projects/{PID}/job",
headers={**H, "Accept-Encoding": "gzip"},
)
resp.raise_for_status()
open(f"{PID}.famc", "wb").write(resp.content)
The downloaded FAMC blob is opaque; treat it as one binary file. Round-trip safety is guaranteed only against POST /projects/{project_id}/job on a project owned by the same user; do not edit the bytes by hand.
Flow: clone a job into a new project¶
Reproduce a quote on a different machine or material without re-running automation.
# 1. Download from the source project
src = requests.get(f"{API}/projects/{SRC_PID}/job", headers=H).content
# 2. Create a fresh project (different machine, material, customer, etc.)
dst = requests.post(
f"{API}/projects",
json={"name": "Bracket v3 / DMU 50", "product_id": "<other-product-id>"},
headers=H,
).json()
# 3. Upload the source job into it
requests.post(
f"{API}/projects/{dst['id']}/job",
files={"file": ("job.famc", src, "application/octet-stream")},
headers=H,
).raise_for_status()
# Open in the UI to inspect:
print(f"https://app.autonomiq.de/projects/{dst['id']}")
Flow: visually inspect a job from a webhook delivery¶
Pair this with the task.failed event so an operator can open the failing project the instant it surfaces.
# Inside your webhook handler …
if event["type"] == "task.failed":
project_id = event["data"]["project_id"]
notify_team(
f"Automation failed on {project_id}. "
f"Open: https://app.autonomiq.de/projects/{project_id}"
)
Restore an earlier snapshot¶
Each POST /projects/{project_id}/job advances the project's current_job_id and pushes the previous one onto the undo stack. To roll back, download the current job before uploading; if the upload introduces issues, re-upload the saved file to revert.
backup = requests.get(f"{API}/projects/{PID}/job", headers=H).content
open(f"{PID}-pre-edit.famc", "wb").write(backup)
# … upload edited job …
# Restore if needed
requests.post(
f"{API}/projects/{PID}/job",
files={"file": ("rollback.famc", backup, "application/octet-stream")},
headers=H,
).raise_for_status()
What's not exposed (yet)¶
The internal API has more visualization surface than the public namespace. These are intentional gaps:
- Direct toolpath fetch (
/cam/toolpath_viz/*): high-volume binary streaming used by the SvelteKit canvas; deferred until customers want to render in their own viewer. - BREP / mesh download (
/cam/workpiece/{id}/brep): already covered by the FAMC blob; standalone access not needed. - Server-Sent Events for live viewport updates: internal-only; pair the public API with webhooks instead.
- Granular setup / block / operation read (
/cam/setup,/cam/block,/cam/operation): the FAMC blob is the canonical read surface; piecewise reads would re-introduce the consistency problems the data-oriented format is designed to avoid.