Documentation
Exact CAD
Analyze exact geometry, export STEP, and inspect assembly relationships from scene snapshots or saved drawings.
Send these requests to your own running sidecar. Values stay in this browser.
How this works
The sidecar listens on a loopback port chosen at startup and prints it in its ready line; use that URL and the CADCAMFUN_TOKEN it was started with. Requests go straight from this page to that address.
The sidecar sends CORS headers only to the Tauri origins and to http://localhost or http://127.0.0.1 on any port. From the hosted docs the browser blocks the response, so run the docs locally (bun run dev in packages/web) to use the playground, or copy the request as curl. To experiment without touching real data, start the sidecar with CADCAMFUN_DATA_DIR pointed at a throwaway directory — see the API walkthrough.
Operations
5 endpoints in the cadExact group, generated from the sidecar's own OpenAPI document. Protected operations take Authorization: Bearer $CADCAMFUN_TOKEN; see authentication. Behaviour and limits are in the subsystem guide.
| post | /api/cad/exact/analyze | cadExact.analyze |
| post | /api/cad/exact/step | cadExact.step |
| post | /api/cad/exact/assembly | cadExact.assembly |
| post | /api/cad/exact/setups | cadExact.setups |
| post | /api/cad/exact/hole | cadExact.hole |
/api/cad/exact
cadExact.analyze Requires Authorization: Bearer <token>.
{ elements?: object[] drawingId?: string ids?: string[] machining?: boolean }
200 object application/json
{ parts: Array<{ id: string name: string valid: boolean issues: string[] volume: number area: number centroid: { x: number y: number z: number } bounds: { min: { x: number y: number z: number } max: { x: number y: number z: number } } faces: number edges: number vertices: number surfaces: { [key: string]: number } throughHoles?: number holes: Array<{ entry: { x: number y: number z: number } direction: { x: number y: number z: number } diameter: number depth: number form: "simple" | "counterbore" | "countersink" bottom: "through" | "flat" | "drill-point" headDiameter?: number headDepth?: number }> machining: { prismatic: true holes: number pockets: number outlines: number top: number bottom: number islands?: number sideHoles?: number hiddenFaces?: number } | { prismatic: false reason: string } bosses: Array<{ diameter: number length: number free: "near" | "far" | "both" | "none" origin: { x: number y: number z: number } axis: { x: number y: number z: number } }> nurbsFaces?: Array<{ face: number normal: { x: number y: number z: number } spread: number trimmed: boolean }> fillets?: Array<{ face: number kind: "cylinder" | "torus" radius: number convex: boolean length: number }> swarfWalls?: Array<{ face: number kind: "plane" | "cone" | "cylinder" near: { x: number y: number z: number } height: number lean: number concaveRadius?: number }> faceNames?: string[] repair?: { verticesWelded: number edgesWelded: number collapsedUses: number validAfter: boolean issuesAfter: string[] } }> skipped: Array<{ id: string name: string reason: string }> totals: { parts: number volume: number area: number } }
400 BadRequestEncoded application/json
BadRequestEncoded
401 UnauthorizedEncoded application/json
UnauthorizedEncoded
403 ForbiddenEncoded application/json
ForbiddenEncoded
404 NotFoundEncoded application/json
NotFoundEncoded
500 InternalErrorEncoded application/json
InternalErrorEncoded
SDK example
import { CadCam } from "@cadcamfun/api/sdk"
const client = CadCam.make({
baseUrl: process.env.CADCAMFUN_URL!,
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
})
// CadExactAnalyzeInput
const result = await client.cadExact.analyze({
elements: [
{}
],
drawingId: "",
ids: [
""
],
machining: false
}) curl
curl --request POST "${CADCAMFUN_URL}/api/cad/exact/analyze" \
--header "Authorization: Bearer ${CADCAMFUN_TOKEN}" \
--header "Content-Type: application/json" \
--data-binary @request.json Try it
cadExact.step Requires Authorization: Bearer <token>.
{ elements?: object[] drawingId?: string ids?: string[] faceted?: boolean author?: string }
200 object application/json
{ step?: string parts: Array<{ id: string name: string exact: boolean faces: number valid: boolean note?: string }> skipped: Array<{ id: string name: string reason: string }> }
400 BadRequestEncoded application/json
BadRequestEncoded
401 UnauthorizedEncoded application/json
UnauthorizedEncoded
403 ForbiddenEncoded application/json
ForbiddenEncoded
404 NotFoundEncoded application/json
NotFoundEncoded
500 InternalErrorEncoded application/json
InternalErrorEncoded
SDK example
import { CadCam } from "@cadcamfun/api/sdk"
const client = CadCam.make({
baseUrl: process.env.CADCAMFUN_URL!,
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
})
// CadExactStepInput
const result = await client.cadExact.step({
elements: [
{}
],
drawingId: "",
ids: [
""
],
faceted: false,
author: ""
}) curl
curl --request POST "${CADCAMFUN_URL}/api/cad/exact/step" \
--header "Authorization: Bearer ${CADCAMFUN_TOKEN}" \
--header "Content-Type: application/json" \
--data-binary @request.json Try it
cadExact.assembly Requires Authorization: Bearer <token>.
{ elements?: object[] drawingId?: string washers?: boolean }
200 object application/json
{ parts: number interference: { clashes: Array<{ a: string b: string aName: string bName: string volume: number centroid: { x: number y: number z: number } }> expected: Array<{ a: string b: string aName: string bName: string volume: number note: string }> touching: Array<{ a: string b: string }> undetermined: Array<{ a: string b: string reason: string }> checked: number } clearance?: Array<{ a: string b: string aName: string bName: string distance: number overlap: boolean }> bom: Array<{ item: number name: string designation?: string material?: string quantity: number volume: number mass?: number parts: string[] }> joints: Array<{ parent: string child: string parentName: string childName: string kind: "revolute" | "fixed" origin: { x: number y: number z: number } axis: { x: number y: number z: number } axes: number }> fasteners: { plans: Array<{ id: string size: string threadName: string designation: string length: number seat: { x: number y: number z: number } direction: { x: number y: number z: number } bodies: string[] tapped?: string grip: number engagement?: number headWasher?: { designation: string inner: number outer: number thickness: number } nutWasher?: { designation: string inner: number outer: number thickness: number } nutWasherAt?: { x: number y: number z: number } nut?: { designation: string across: number height: number at: { x: number y: number z: number } } warnings: string[] }> unfastened: Array<{ bodies: string[] at: { x: number y: number z: number } reason: string }> existing: number } skipped: Array<{ id: string name: string reason: string }> }
400 BadRequestEncoded application/json
BadRequestEncoded
401 UnauthorizedEncoded application/json
UnauthorizedEncoded
403 ForbiddenEncoded application/json
ForbiddenEncoded
404 NotFoundEncoded application/json
NotFoundEncoded
500 InternalErrorEncoded application/json
InternalErrorEncoded
SDK example
import { CadCam } from "@cadcamfun/api/sdk"
const client = CadCam.make({
baseUrl: process.env.CADCAMFUN_URL!,
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
})
// CadExactAssemblyInput
const result = await client.cadExact.assembly({
elements: [
{}
],
drawingId: "",
washers: false
}) curl
curl --request POST "${CADCAMFUN_URL}/api/cad/exact/assembly" \
--header "Authorization: Bearer ${CADCAMFUN_TOKEN}" \
--header "Content-Type: application/json" \
--data-binary @request.json Try it
cadExact.setups Requires Authorization: Bearer <token>.
{ elements?: object[] drawingId?: string ids?: string[] fixture?: "bottom" | "none" allowed?: Array<"+Z" | "-Z" | "+X" | "-X" | "+Y" | "-Y"> }
200 object application/json
{ parts: Array<{ id: string name: string plan: { setups: Array<{ orientation: "+Z" | "-Z" | "+X" | "-X" | "+Y" | "-Y" faces: number[] area: number share: number holes: Array<{ entry: { x: number y: number z: number } direction: { x: number y: number z: number } diameter: number depth: number form: "simple" | "counterbore" | "countersink" }> prismatic: { ok: true holes: number pockets: number outlines: number } | { ok: false reason: string } }> uncovered: Array<{ face: number kind: string area: number reason: string }> held: Array<{ face: number kind: string area: number }> indexed: Array<{ entry: { x: number y: number z: number } direction: { x: number y: number z: number } diameter: number depth: number form: "simple" | "counterbore" | "countersink" }> reach: Array<{ orientation: "+Z" | "-Z" | "+X" | "-X" | "+Y" | "-Y" faces: number area: number share: number }> faces: number area: number notes: string[] } }> skipped: Array<{ id: string name: string reason: string }> }
400 BadRequestEncoded application/json
BadRequestEncoded
401 UnauthorizedEncoded application/json
UnauthorizedEncoded
403 ForbiddenEncoded application/json
ForbiddenEncoded
404 NotFoundEncoded application/json
NotFoundEncoded
500 InternalErrorEncoded application/json
InternalErrorEncoded
fetch example
// Not generated in the Promise SDK (multipart, binary or raw body): call it with fetch.
const response = await fetch(`${process.env.CADCAMFUN_URL}/api/cad/exact/setups`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
}) curl
curl --request POST "${CADCAMFUN_URL}/api/cad/exact/setups" \
--header "Authorization: Bearer ${CADCAMFUN_TOKEN}" \
--header "Content-Type: application/json" \
--data-binary @request.json Try it
cadExact.hole Requires Authorization: Bearer <token>.
{ elements?: object[] drawingId?: string id: string hole?: number boss?: number fillet?: number nurbs?: number distance?: number direction?: { x: number y: number z: number } mode?: "move" | "offset" | "draft" angle?: number neutral?: number pull?: { x: number y: number z: number } tolerance?: number radius?: number diameter?: number taper?: number fill?: boolean }
200 object | object | object | object | object application/json
{ ok: true id: string name: string hole: number holes: number before: { diameter: number depth: number form: "simple" | "counterbore" | "countersink" } edit: { kind: "resize" diameter: number taper?: number } | { kind: "fill" } volume: number originalVolume: number volumeChange: number faces: number valid: boolean } | { ok: true id: string name: string boss: number bosses: number before: { diameter: number length: number } diameter: number taper?: number volume: number originalVolume: number volumeChange: number faces: number valid: boolean } | { ok: true id: string name: string fillet: number fillets: number before: { radius: number convex: boolean } radius: number volume: number originalVolume: number volumeChange: number faces: number valid: boolean } | { ok: true id: string name: string nurbs: number nurbsFaces: number mode: "move" | "offset" | "draft" before: { normal: { x: number y: number z: number } spread: number } distance?: number direction?: { x: number y: number z: number } angle?: number approximate?: { deviation: number } volume: number originalVolume: number volumeChange: number faces: number valid: boolean } | { ok: false error: string }
400 BadRequestEncoded application/json
BadRequestEncoded
401 UnauthorizedEncoded application/json
UnauthorizedEncoded
403 ForbiddenEncoded application/json
ForbiddenEncoded
404 NotFoundEncoded application/json
NotFoundEncoded
500 InternalErrorEncoded application/json
InternalErrorEncoded
fetch example
// Not generated in the Promise SDK (multipart, binary or raw body): call it with fetch.
const response = await fetch(`${process.env.CADCAMFUN_URL}/api/cad/exact/hole`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
}) curl
curl --request POST "${CADCAMFUN_URL}/api/cad/exact/hole" \
--header "Authorization: Bearer ${CADCAMFUN_TOKEN}" \
--header "Content-Type: application/json" \
--data-binary @request.json Try it
Schemas
Named schemas reachable from this group's parameters, bodies and responses. A ? marks an optional field; | null marks a field that may be present with a null value.
BadRequestEncoded{ _tag: "BadRequest" message: string }
ForbiddenEncoded{ _tag: "Forbidden" message: string }
InternalErrorEncoded{ _tag: "InternalError" message: string }
NotFoundEncoded{ _tag: "NotFound" message: string }
Calling this group
Operation ids have the form cadExact.<name>. The generated Promise SDK (@cadcamfun/api/sdk) exposes most of them as client.<namespace>.<method>(input), where input is one flat object of path parameters and body fields; each card's SDK example shows the exact accessor and input type. Multipart uploads, binary or JavaScript responses and raw webhooks are not generated; those cards show fetch instead.
import { CadCam, ClientError } from "@cadcamfun/api/sdk"
const client = CadCam.make({
baseUrl: process.env.CADCAMFUN_URL!,
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
})
try {
await client.projects.list()
} catch (error) {
if (error instanceof ClientError) {
// Transport | UnexpectedStatus | UnsupportedContentType | MalformedResponse | SseEventTooLarge
} else {
// a declared error body: switch on error._tag
}
} Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 on every call | Token from a previous launch, or missing Bearer prefix | Send Authorization: Bearer <token> with the token the sidecar was started with. |
| 400 before anything happens | Body or parameter does not match the schema | Compare the payload with the request schema on the card. |
| 403 or 404 on a record you can see elsewhere | The acting account differs | Send the right x-session-token, or use the local profile that owns the record. |
| 409 | Conflicting state, such as a duplicate name or a stale branch head | Re-read the resource and retry with current data. |
| Try it says "blocked by CORS" | The docs are served from a non-loopback origin | Run the docs locally or copy the request as curl. |
| Connection refused | The sidecar restarted on a new port | Read the port from the new ready line. |