Documentation
API walkthrough with captured responses
Exercise health, authorization, project creation, and preference persistence with real handler responses from an isolated database.
Environment and captured responses
The responses on this page were captured from the actual sidecar routes on 15 October 2026 using apps/sidecar/test/helpers.ts. That harness builds the application handlers with a migrated in-memory SQLite database, a disposable file directory, the direct AI host, and no provider calls. The requests go through the HTTP router in-process; this run does not exercise the Tauri launcher, network sockets, TLS, or a paired phone.
The response bodies below are unedited. Identifiers and timestamps therefore belong to that disposable run. Your instance returns its own values. Use the project identifier returned by your create request rather than reuse the captured identifier.
CADCAMFUN_TOKEN=local-development-token \
CADCAMFUN_DATA_DIR=/tmp/cadcamfun-api-walkthrough \
CADCAMFUN_MIGRATIONS_DIR="$PWD/packages/db/drizzle" \
CADCAMFUN_AI_HOST=direct \
CADCAMFUN_AI_OFFLINE=1 \
bun --no-env-file apps/sidecar/src/main.ts This example token is only for an isolated development process. Choose your own value, keep the terminal open, and read the port from the JSON ready event. In a second terminal, set the connection variables below after replacing READY_PORT. The sidecar chooses a new port on another launch.
export CADCAMFUN_URL="http://127.0.0.1:READY_PORT"
export CADCAMFUN_TOKEN="local-development-token" The on-disk development database differs from the capture's in-memory database. If you reuse that data directory, previously created projects and preferences remain. Use a separate disposable directory for a fresh run. The packaged desktop uses its native application data directory instead.
Check health
/api/health is the public probe. It confirms that this route answers; it does not test credentials, a model provider, or manufacturing resources.
curl --silent --show-error "$CADCAMFUN_URL/api/health" {
"status": "ok",
"timestamp": "2026-10-15T02:43:50.682Z"
} The native /health and /version operations require the application bearer token. Read their exact contracts in the system reference.
Read and create a project
curl --silent --show-error "$CADCAMFUN_URL/api/projects" \
--header "Authorization: Bearer $CADCAMFUN_TOKEN" [] The response is a plain array, without a data or success wrapper. A structurally valid but incomplete create request is rejected by business validation:
curl --silent --show-error --request POST "$CADCAMFUN_URL/api/projects" \
--header "Authorization: Bearer $CADCAMFUN_TOKEN" \
--header "Content-Type: application/json" \
--data '{}' {
"_tag": "BadRequest",
"message": "Project name is required"
} The transport schema makes name optional, but the handler requires a non-empty value. To create the project:
curl --silent --show-error --request POST "$CADCAMFUN_URL/api/projects" \
--header "Authorization: Bearer $CADCAMFUN_TOKEN" \
--header "Content-Type: application/json" \
--data '{"name":"API walkthrough","description":"Disposable documentation example"}' {
"id": "ccaff34c-49f3-4a23-a6b6-427745f9641a",
"name": "API walkthrough",
"description": "Disposable documentation example",
"createdAt": "2026-10-15T02:43:50.741Z",
"updatedAt": "2026-10-15T02:43:50.741Z",
"ownerId": "894c5064-576e-4e43-b7f0-79c6120e8345",
"organizationId": null,
"isPublic": false
} The create result is the new project row. Omitted isPublic becomes false in this run; no organization is selected. The owner is the acting local profile. Assigning an organization requires membership; updating an existing project also checks its owner or organization role.
Read back related data
Copy the identifier returned by your create request into PROJECT_ID, then read the detail route:
export PROJECT_ID="your-returned-project-id"
curl --silent --show-error "$CADCAMFUN_URL/api/projects/$PROJECT_ID" \
--header "Authorization: Bearer $CADCAMFUN_TOKEN" {
"id": "ccaff34c-49f3-4a23-a6b6-427745f9641a",
"name": "API walkthrough",
"description": "Disposable documentation example",
"createdAt": "2026-10-15T02:43:50.741Z",
"updatedAt": "2026-10-15T02:43:50.741Z",
"ownerId": "894c5064-576e-4e43-b7f0-79c6120e8345",
"organizationId": null,
"isPublic": false,
"owner": {
"id": "894c5064-576e-4e43-b7f0-79c6120e8345",
"name": "Local user",
"email": "local@cadcamfun.local"
},
"organization": null,
"_count": {
"drawings": 0,
"components": 0
}
} Detail includes the owner, nullable organization, and drawing/component counts. Creation and retrieval have related but different response schemas. A missing or inaccessible project returns 404 with Project not found or access denied; callers should not infer a private project's existence from that result.
Projects API also documents update and deletion. Updating requires a non-empty name; deleting requires the owner or an organization administrator. Do not implement update as an arbitrary JSON patch without following its payload contract.
Paged lists such as machine configurations accept page (default 1) and limit (default 20, maximum 100) and return a pagination object with total and totalPages. Request the next page instead of raising limit past the cap; larger values are clamped to 100.
Persist a preference
The key-value API demonstrates a second response shape and missing-resource behavior. A key that has not been saved returns 404:
curl --silent --show-error "$CADCAMFUN_URL/api/kv/docs.walkthrough.units" \
--header "Authorization: Bearer $CADCAMFUN_TOKEN" {
"_tag": "NotFound",
"message": "Key not found"
} Save a JSON-compatible value with PUT. This is a preference example; it does not globally change the geometry kernel's units.
curl --silent --show-error --request PUT "$CADCAMFUN_URL/api/kv/docs.walkthrough.units" \
--header "Authorization: Bearer $CADCAMFUN_TOKEN" \
--header "Content-Type: application/json" \
--data '{"value":"mm"}' {
"key": "docs.walkthrough.units",
"value": "mm",
"updatedAt": "2026-10-15T02:43:50.755Z"
} Reading the same key returns the stored entry, including its update timestamp. The response does not wrap the value in a project record or success envelope.
{
"key": "docs.walkthrough.units",
"value": "mm",
"updatedAt": "2026-10-15T02:43:50.755Z"
} Use GET /api/kv?prefix=docs.walkthrough. to list matching entries, or DELETE the encoded key to remove it. The store rejects blank keys, overlong keys, and values outside its JSON-compatible domain. It is not a credential vault.
Handle failures and retries
| Result | Next action |
|---|---|
| 401 on a protected call | Verify the current launch token and its type; use the newly announced URL after a restart. |
| 400 on project creation | Read the business error and correct the request; resending the same missing name will fail again. |
| 404 on a project or preference | Check the identifier/key and acting account; apply the resource's missing/access policy. |
| Connection loss during a write | Read back the resulting resource or state before repeating the write. These create endpoints do not declare an idempotency-key contract. |
| 5xx | Inspect the sidecar logs and failed service. Do not assume a response error proves that no earlier persistent operation took effect. |
In production clients, check response.ok and decode the appropriate success or error body. Avoid relying on a uniform envelope: this walkthrough alone includes an array, plain records, and tagged failures.
Next integration steps
Use the full reference to select a resource. The machining endpoints distinguish computation from saving a toolpath; the history endpoints distinguish working-copy changes from commits and remote synchronization. The AI resource covers session identifiers and streaming controls.
Read the running sidecar's /api/openapi.json when integrating a different build. The downloadable documentation snapshot describes the checked-out contract; it cannot establish which binary another machine is running.
All captured responses at a glance
The responses on this page were captured from a real sidecar with a fresh database. Identifiers and timestamps will differ on your machine; shapes and statuses will not.
| Step | Path | Status | Body (truncated) |
|---|---|---|---|
| Public health | /api/health | 200 | {"status": "ok", "timestamp": "2026-10-15T02:43:50.682Z"} |
| Missing bearer | /api/projects | 401 | {"_tag": "Unauthorized", "message": "Unauthorized"} |
| Empty projects | /api/projects | 200 | [] |
| Missing project name | /api/projects | 400 | {"_tag": "BadRequest", "message": "Project name is required"} |
| Create project | /api/projects | 201 | {"id": "ccaff34c-49f3-4a23-a6b6-427745f9641a", "name": "API walkthrough", "description": "Disposable documenta… |
| Read project | /api/projects/ccaff34c-49f3-4a23-a6b6-427745f9641a | 200 | {"id": "ccaff34c-49f3-4a23-a6b6-427745f9641a", "name": "API walkthrough", "description": "Disposable documenta… |
| Missing preference | /api/kv/docs.walkthrough.units | 404 | {"_tag": "NotFound", "message": "Key not found"} |
| Save preference | /api/kv/docs.walkthrough.units | 200 | {"key": "docs.walkthrough.units", "value": "mm", "updatedAt": "2026-10-15T02:43:50.755Z"} |
| Read preference | /api/kv/docs.walkthrough.units | 200 | {"key": "docs.walkthrough.units", "value": "mm", "updatedAt": "2026-10-15T02:43:50.755Z"} |
The whole tour as one script
#!/usr/bin/env bash
set -euo pipefail
: "${CADCAMFUN_URL:?set to the sidecar URL}" "${CADCAMFUN_TOKEN:?set to the launch token}"
auth=(--header "Authorization: Bearer $CADCAMFUN_TOKEN")
json=(--header "Content-Type: application/json")
curl -sS "$CADCAMFUN_URL/api/health"; echo
curl -sS -o /dev/null -w "no token -> %{http_code}\n" "$CADCAMFUN_URL/api/projects"
curl -sS "${auth[@]}" "$CADCAMFUN_URL/api/projects"; echo
curl -sS "${auth[@]}" "${json[@]}" -d '{}' "$CADCAMFUN_URL/api/projects"; echo # 400
id=$(curl -sS "${auth[@]}" "${json[@]}" \
-d '{"name":"API walkthrough","description":"Disposable documentation example"}' \
"$CADCAMFUN_URL/api/projects" | sed -E 's/.*"id":"([^"]+)".*/\1/')
curl -sS "${auth[@]}" "$CADCAMFUN_URL/api/projects/$id"; echo
key=docs.walkthrough.units
curl -sS -w " %{http_code}\n" "${auth[@]}" "$CADCAMFUN_URL/api/kv/$key" # 404 first time
curl -sS -X PUT "${auth[@]}" "${json[@]}" -d '{"value":{"units":"mm"}}' "$CADCAMFUN_URL/api/kv/$key"; echo
curl -sS "${auth[@]}" "$CADCAMFUN_URL/api/kv/$key"; echo The script uses sed to extract the id so it has no dependencies; with jq installed, prefer jq -r .id. Run it against a disposable data directory: it creates a real project.
Clean up after the tour
curl -sS -X DELETE --header "Authorization: Bearer $CADCAMFUN_TOKEN" "$CADCAMFUN_URL/api/projects/$id"
curl -sS -X DELETE --header "Authorization: Bearer $CADCAMFUN_TOKEN" "$CADCAMFUN_URL/api/kv/docs.walkthrough.units" Deleting the project cascades to its drawings, components, toolpaths, history and workflow runs. The key-value entry is independent and must be removed separately.