Skip to content

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:

https://app.autonomiq.de/projects/<project_id>

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.