Documentation
Generate a native manufacturing program
Capture a real part, evaluate its manufacturing job, inspect the posted NC evidence, and save a document that can be checked again.
Know which result you are requesting
Native manufacture is a deterministic CAD/CAM computation, independent of a language model. POST /api/toolpaths/manufacture accepts an explicit CAD snapshot, prepares manufacturing resources, plans or accepts ordered operations, computes cutting data, generates toolpaths, posts one NC program, and independently replays that text. The response includes the evidence supporting its release level.
This endpoint does not create a drawing, save a toolpath, or update the editor. A successful response is a value to inspect and persist deliberately. It is different from /api/toolpaths/generate, which adapts the application generator settings for mill/lathe/printer output, and from /api/toolpaths/verify, which replays a supplied NC/program against explicitly modelled stock and a tool.
Use the machining endpoints for request/response schemas, CAM reference for the core representations, and saved program reference for persistence behavior. The following job is deliberately small enough to reproduce and inspect without editing an existing project.
Send a complete, validated snapshot
Save this JSON as native-job.json. It describes a 40 × 40 × 10 mm POM blank centered at (20,20,5), surrounded by 2 mm of stock on each X/Y side and 1 mm above. The payload was decoded by the real CamKernelRequest schema and evaluated by the kernel; its baseline result contains three planned operations. Always inspect the returned claims rather than hard-coding an expected release in a client.
{
"schemaVersion": 1,
"id": "blank-job",
"name": "POM blank",
"material": "POM",
"elements": [{
"id": "blank",
"type": "cube",
"x": 20, "y": 20, "z": 5,
"width": 40, "height": 40, "depth": 10
}],
"stock": { "x": 20, "y": 20, "width": 44, "height": 44, "depth": 11 },
"resolution": 0.5
} curl --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @native-job.json \
"$CADCAMFUN_URL/api/toolpaths/manufacture" > native-result.json The shell file captures the exact response for inspection. Supplying the same captured request yields deterministic native output; using a new part position, cutter, operation, or quality control is a different job. Request identity labels are useful for tracking, but the artifact's digests bind its actual source and NC content.
Resolve stock and work coordinates
Snapshot stock uses center X/Y and full width/height/depth. The snapshot adapter first builds the selected part geometry, finds its lowest Z, and places the stock bottom there; its top is that bottom plus the declared depth. In the example, the part extends from Z0 to Z10 and the stock from Z0 to Z11. Stock bounds in X/Y are −2 to 42.
The adapter uses the explicit dimensions for those bounds. It does not add the stock record's display allowance again, and a stock topZ field does not replace the lowest-part anchoring in this native snapshot adapter. Keep the distinction between editor metadata and the fields actually consumed to construct a manufacturing job.
Work origin defaults to stock-center: the stock center X/Y at its top Z. stock-corner chooses minimum X/Y at the same top. Input operation geometry is in CAD world millimetres, while resulting program moves/NC are in work coordinates. Conventional cutting goes below work Z0. workOffset is optional; the program default is G54.
Without supplied stock, the lower-level job preparation encloses part bounds with 2 mm extra on each X/Y side and 1 mm above. A part outside explicit stock is rejected; increasing requested cutting depth does not make incompatible stock contain the part.
Select material, machine, and cutters
Material is a lookup string resolved against the kernel's material library, including supported IDs, names, and aliases. Unknown material returns a typed preparation issue. The HTTP snapshot's optional machine is a registered preset ID: vmc-standard, haas-vf2, hsc-mill, desktop-mill, or cnc-router. Omitting it uses vmc-standard. Presets describe typical machine classes and limits, not a qualified model of an individual installation.
Omitting tools uses the default cutter crib. Supplying tools replaces that crib and requires 1–200 cutter records. A cutter identifies its kind, diameter, flute count, material/coating, flute length, shank diameter, and stickout. Optional holder dimensions, maximum RPM, pocket number, and kind-specific geometry refine generation and clearance. Flutes must be an integer from 1 to 24; explicit pocket numbers are 1–999.
Operation tool IDs must name cutters in that supplied library. Duplicate cutter IDs, invalid dimensions, and unreachable strategy/tool combinations produce issues rather than guessed substitutions. The schema accepts flat, ball, bull, chamfer, spot, drill, facemill, threadmill, and engraver kinds.
The public snapshot machine string does not accept a custom machine record. A code integration calling the lower-level ManufacturingJob API can provide machine limits, travel, and table geometry explicitly. Do not send that record where the HTTP schema expects a preset string.
Plan automatically or specify machining order
When operations are absent, the planner derives them from the part. An explicit operations array is authoritative machining order, not a list of suggestions to be reordered silently. Each operation has a unique ID and a tool reference. Supported strategy records cover face, adaptive, pocket, profile, bore, drill, thread, engrave, chamfer, and surface work, with geometry appropriate to each.
A profile uses a loop, inside/outside side, and world-coordinate top/bottom. A pocket/adaptive cut uses a closed boundary with optional island rings. Drilling uses points plus top/bottom. A thread-mill record includes center, diameter, pitch, internal flag, top, and length. A surface record chooses roughing, parallel, waterline, or steep-shallow behavior; a rest reference must identify appropriate previous work.
Per-operation process overrides can include RPM, feed, plunge feed, stepdown, stepover, coolant, and radial engagement. Missing values come from material/cutter/machine cutting data. Stepover is a percentage from 1 to 100; stepdown and feeds are positive. The artifact records overridden fields separately from computed parameters so a reviewer can see where process choices came from.
The native kernel carries provisional stock between operations and posts their combined IR once. By contrast, combineCamOperations for saved generic operation sections joins already generated NC text; it does not transform those sections into an integrated controller program. Use the native artifact when that integrated generation and replay is required.
Set quality controls and understand their cost
| Input | Meaning and bounds |
|---|---|
finishAllowance | 0–5 mm roughing allowance; omitted uses the material's default. |
scallop | Positive, at most 1 mm; default 0.01 mm for native finishing. |
tolerance | Positive path tolerance; native default 0.01 mm. |
resolution | Positive replay cell size; controls the stock evidence's spatial resolution. |
deburr | Positive, at most 5 mm; asks the planner to add supported top-edge chamfer work. |
subprograms | Optional translated-repeat emission where the dialect supports it, such as Fanuc/Haas M98 subprograms. |
The request supports 1–2,000 CAD elements and at most 500 explicit operations. Smaller tolerances and replay cells increase computational work and do not automatically prove unsupported geometry. Preserve the reported resolution with the result. A viewport mesh and a downsampled stock preview are display outputs, not an independent finer simulation.
Native posting sets tool numbers from the cutter assignments and requests retract-before-tool-change. The posts format coordinates with fixed decimals. Inspect the actual NC and selected dialect; a controller name does not eliminate the need to validate the installation's post behavior.
Interpret status, claims, and release
The result is a union: status: "failed" with issues, or status: "ok" with an artifact. An ok artifact can still have release: "blocked". Read both layers; checking HTTP status or the outer status alone is insufficient.
The artifact retains ordered operation outcomes, cutting data, program IR, used cutters, NC, stock statistics, cycle-time estimates, issues, and identity digests. Claims have passed, failed, unsupported, or unresolved status. They cover cutting data, machine limits, operation completion, rapid/holder clearance, gouging, material removal, independent NC replay, machine travel, and machine/table clearance.
Hard error issues or empty NC block release. With no hard failure, incomplete evidence produces preview unless the release rule is satisfied. The current rule allows an unsupported machine-travel claim while still returning verified-program; the built-in presets do not all provide explicit axis travel. Check that claim when deciding whether the result covers a particular machine.
Evidence has a model boundary
The native stock/holder replay is a three-axis height-field check. The public native snapshot has no fixture-envelope field. Standalone verification accepts fixture envelopes, but they are not added to native evidence by implication. A verified-program label is evidence about its captured model and checks, not a machine certification.
Kernel results identify their producer: the algorithm identifier is cadcamfun-cam-kernel@1 and the contract schema version is 1 (packages/core/src/cam/kernel/execute.ts, contracts.ts). Compare both when deciding whether stored evidence came from the same kernel.
Create a portable document from the exact result
A CamProgramDocument preserves NC, program, generator/printer settings, stock, and drawing snapshot. Optional kernelRequest/kernelArtifact retain native source evidence. This example converts the captured request and result into that document without saving it; run it in a workspace depending on core, API, and Effect, such as apps/sidecar.
import { Schema } from "effect"
import { cam } from "@cadcamfun/core"
import { CamKernelRequest, CamKernelResult, CamProgramDocument } from "@cadcamfun/api"
const request = Schema.decodeUnknownSync(CamKernelRequest)(await Bun.file("native-job.json").json())
const result = Schema.decodeUnknownSync(CamKernelResult)(await Bun.file("native-result.json").json())
if (result.status !== "ok" || result.value.release === "blocked") {
throw new Error("The captured job has no releasable artifact")
}
const document = Schema.decodeUnknownSync(CamProgramDocument)({
format: "cadcamfun-cam", version: 1,
gcode: result.value.nc, program: result.value.program,
settings: cam.generator.DEFAULT_SETTINGS,
printer: cam.generator.DEFAULT_PRINTER_EXTRAS,
stock: request.stock,
drawing: { elements: request.elements, stock: request.stock },
kernelRequest: request, kernelArtifact: result.value
})
await Bun.write("portable-program.json", JSON.stringify(document, null, 2)) The example requires explicit stock, as the supplied minimal request has. Its generic editor settings are reopening controls, while the captured kernelRequest is the native source of truth. Preserve all actual editor settings when capturing from an application workspace.
Save against a real drawing
Save the document separately through POST /api/drawings/:id/toolpaths, with name, G-code, and data containing the complete portable document. Use a real drawing ID accessible to the caller. Portable saves require project-owner or organization ADMIN/MANAGER write access; a successful calculation alone grants no persistence permission.
The sidecar decodes the document, checks row NC equals document NC, and reruns a captured kernel request before trusting a new native artifact. It compares the resulting artifact, program, and original NC. Edited evidence, a blocked rerun, or inconsistent bytes are refused. Client-provided verification/sourceRevision fields do not establish trust.
When captured selected elements and stock match the associated drawing, the service derives a drawing revision digest. A saved native artifact can lack that revision when the source does not match the current drawing. Keep that distinction visible: valid captured output is not necessarily fresh output for the latest stored model.
See toolpath persistence endpoints and exact CAD analysis when assembling a richer capture/save flow. Avoid the project toolpath variant unless its distinct query-parameter contract is intended.
Regenerate after changes and diagnose rejection
Changing geometry, stock, origin, tools, material, machine, operation order, or NC changes the evidence relationship. Regenerate from the updated captured request. A plain NC edit can remain useful ordinary text, but it must not carry an earlier native artifact as proof for new bytes. The save service strips incompatible native metadata or rejects an inconsistent new document.
Unknown machine preset is an adapter validation error. Unknown material/tool, invalid stock containment, empty geometry, and unsupported machining produce preparation/planning issues. Gouge, rapid-in-stock, holder/table collision, and replay mismatch point to generated motion/evidence. Locate the operation ID, stage, line, and point in the issue before changing process controls.
A source payload can pass JSON schema decoding and still fail to produce a valid job. Conversely, an artifact can exist with a blocked release. Keep the original request/result pair when diagnosing either condition, rather than overwriting it with a speculative settings change.
Implementation provenance: packages/api/src/cam-kernel.ts, cam-program.ts, core cam/kernel/snapshot.ts, execute.ts, schema.ts, and sidecar services/cam-program.ts. Focused evidence tests are packages/core/src/cam/kernel/kernel.test.ts and apps/sidecar/test/cam-program.test.ts.
Walk through the example result
Without an operations array the planner chose three operations from the default cutter crib, each with its own tool change. The NC header summarises them before any motion:
%
O1000
(PROGRAM: POM BLANK)
(UNITS: MM)
(WORK OFFSET: G54)
(MACHINE: VERTICAL MACHINING CENTRE BT40, 12 000 RPM, 11 KW)
(MATERIAL: ACETAL POM-C DELRIN)
(STOCK: 44.00 X 44.00 X 11.00 MM)
(OP 1: FACE STOCK TOP | T1 [FACEMILL-50] | S1810 | F815-1629)
(OP 2: 3D ADAPTIVE ROUGHING | T2 [FLAT-16] | S7160 | F2848-5696)
(OP 3: 3D STEEP AND SHALLOW FINISHING | T3 [BALL-10] | S12000 | F1642-3283)
G21 G90 G17 G94 G40 G49 G80
G54
(OPERATION: FACE STOCK TOP)
T1 M6
G43 H1
M3 S1810
(OP1 FACE)
(FACE: FACE STOCK TOP)
G0 X-48.000 Y-22.000 Z10.000
Z5.000
Z2.000
Z1.000
G1 Z-1.000 F815
X48.000 F1629
Y0.000
X-48.000
Y22.000
X48.000
G0 Z2.000 The program ends with G0 Z10.000, M5, M30 and %. Total length: 3071 lines. Because no machine was given, the vmc-standard preset applied, whose post is fanuc: hence the %/O1000 framing, T1 M6 tool changes and G43 H1 length compensation.
Read the cutting data of an operation
Every operation carries a cutting record that shows how its speeds and feeds were derived. These are the values for the roughing operation above:
| Field | Value | Meaning |
|---|---|---|
rpm | 7160 | Spindle speed from Vc and the effective diameter |
vc / vcRecommended | 359.9 / 360 m/min | Achieved and recommended surface speed |
fz | 0.199 mm | Feed per tooth after chip-thinning correction |
chipThickness | 0.159 mm | Resulting average chip thickness |
feed / plungeFeed | 5696 / 2848 mm/min | Cutting and plunge feed |
ap / ae | 10 / 3.2 mm | Axial depth and radial engagement (20 % stepover) |
rampAngle / helixPitch | 5° / 4.398 mm | Entry geometry |
mrr | 182.258 cm³/min | Material removal rate |
powerKw / torqueNm / forceN | 1.862 / 1.986 / 248 | Estimated load, checked against machine limits |
deflectionMm | 0.0157 mm | Estimated tool deflection |
limitedBy, warnings, exceeded | empty | Which limit capped a value; nothing did here |
source reads: "Acetal POM-C (Delrin) (ISO N): Vc 360 m/min, fz 0.159 mm at Ø16, kc1.1 300 N/mm² mc 0.2 (handbook starting values)". The reference block lists the material-table row, the columns used and every multiplying factor (here cutSpeed 1.2, diameterScale 1.326, chipThinning 1.25). Its basis states that these are handbook starting values, not a supplier's certified data for the cutter.
Starting values, not a guarantee
Treat cutting data as a reasoned first try. Check them against your tool supplier's data and the machine before production, and override per operation when you know better: the artifact then records the field in overridden.
Artifact identity
| Field | Example | Hash of |
|---|---|---|
identity.job | aa2159be8c7c4228… | The canonical job |
identity.part | 91a5382540991195… | The part geometry |
identity.nc | 1614df331826682c… | The exact NC text |
identity.algorithm | cadcamfun-cam-kernel@1 | Kernel name and version |
Re-running the same request reproduces the same identities. When the sidecar saves a native artifact, it reruns the captured request and compares; an edited NC changes identity.nc and is rejected as evidence.
Recipe: generate and save from TypeScript
import { CadCam } from "@cadcamfun/api/sdk"
const client = CadCam.make({
baseUrl: process.env.CADCAMFUN_URL!,
headers: { authorization: `Bearer ${process.env.CADCAMFUN_TOKEN}` },
})
const request = JSON.parse(await Bun.file("native-job.json").text())
const result = await client.toolpathGenerator.manufacture(request)
if (result.status === "failed") throw new Error(result.issues.map((i) => i.message).join("; "))
const artifact = result.value
const failed = artifact.claims.filter((claim) => claim.status === "failed")
console.log(artifact.release, failed.map((claim) => `${claim.id}: ${claim.detail}`))
if (artifact.release === "blocked") process.exit(1)
await Bun.write("program.nc", artifact.nc) Saving as a toolpath additionally needs a portable cadcamfun-cam document built from this artifact, its program, the captured request and the drawing snapshot, as described above. The SDK method takes the same JSON object as the HTTP body, typed as ToolpathGeneratorManufactureInput.