G-code from your own scripts

Everything the interface does is available over the API: upload the file, start generation, poll the status, download the G-code. Four calls, no account, no registration — the access token from your credit purchase is the API key.

Built for repeating work: part families with changing dimensions, batches out of a configurator, overnight runs. If you would rather have an AI assistant operate it, use the MCP server, which sits on this same interface.

Credits and the access token are available at www.step2gcode.com — no account, no subscription.

What you should know

  • No free quota: Over the API every new model costs one credit, charged at download. Uploading, generating, status polling and the image preview are free. The browser quota does not apply here — it is tied to a device, and a script has none.
  • What counts is the model, not the call: The same file with a different cutter, depth or origin costs one credit in total. A model already paid for stays free permanently, including in later months, so parameter sweeps do not get expensive.
  • Deterministic: The same file with the same settings always produces the same program. That is what makes the interface usable for automated workflows in the first place.

The four calls

  • POST /api/upload — CAD file as multipart/form-data, returns a file_id (free)
  • POST /api/generate — file_id plus settings (tool, depth, origin), returns a job_id (free)
  • GET /api/status/{job_id} — poll until completed or failed (free)
  • GET /api/preview-image/{job_id} — tool path as a PNG for visual checking (free)
  • GET /api/download/{job_id} — the finished program (1 credit per new model)
  • GET /api/pro/credits/{token} — credits left and models paid for (free)

Every parameter of POST /api/generate

The request object is nested: file_id sits at the top level, everything else lives in blocks. Every block is optional — whatever you leave out keeps its default. Unknown fields are dropped silently, so a typo in a field name does not come back as an error; it comes back as a result that does not match what you asked for.

(top level)

file_idstring, requiredThe id returned by POST /api/upload.
nest_uniform_depthboolfalseOnly when arranging several parts on one sheet: forces one cutting depth for all of them. Without it, STEP parts keep the depth from their 3D geometry while DXF and SVG parts use depth_override.

tool — Cutter

bit_diameternumber, mm6.0Cutter diameter. It has to fit the smallest inner radius of the part.
cutting_lengthnumber, mmemptyUsable flute length. When set, the depth per pass never exceeds it.
tool_type'endmill' | 'vbit''endmill'End mill or V-bit. For laser jobs set laser.enabled instead.
vbit_anglenumber, degrees90Included angle of the V-bit. Only used with tool_type "vbit".
vbit_tip_diameternumber, mm0Diameter of the flattened tip. 0 means pointed, no compensation.
spindle_speedinteger, rpm10000Spindle speed. Overridden by feed_rates when that block is sent.
horizontal_speednumber, mm/min1200Feed in the plane. Also overridden by feed_rates.
vertical_speednumber, mm/min300Plunge feed. Also overridden by feed_rates.

feed_rates — Cutting data

When this block is present, its values replace the three speeds from tool. Important for scripts: there is no server-side material automation — the cutting data you send is used exactly as sent.

auto_calculatebooltrueComes from the interface, where it drives the material preset. Over the API the field has no effect; set it to false for clarity when you send your own values.
spindle_speedinteger, rpm18000Spindle speed.
horizontal_speednumber, mm/min1200Feed in the plane.
vertical_speednumber, mm/min400Plunge feed.

material — Workpiece material

typestring'wood'Material, for example wood, hardwood, plywood, acrylic, aluminum, steel, brass. It only decides from which diameter holes are helically milled rather than drilled — spindle speed and feeds come from tool or feed_rates.

depth — Depth

depth_overridenumber, mmempty = AUTOCutting depth. Empty means: derive it from the geometry (for STEP, the part height). DXF and SVG carry nothing to derive it from, so there the value is effectively required.
step_downnumber, mmempty = AUTODepth per pass. Note: while settings.optimize_passes is true, the value is only an upper bound and the actual step-down is optimised below it. For an exact step-down, set optimize_passes to false.
final_depth_offsetnumber, mm0.1How far the last pass goes below the underside of the part so a cut-out is severed cleanly.

origin — Origin and orientation

The short spelling xy and z is accepted as well and means the same as origin_xy and origin_z.

origin_xy'TL' | 'TR' | 'BL' | 'BR' | 'C''TL'Origin in the plane: top left, top right, bottom left, bottom right or centre.
origin_z'top' | 'spoilboard''top'Z zero on the stock surface or on the spoilboard.
rotation_znumber, degrees0Rotates the part in the plane, for instance to lay it out better on the sheet.
rotation_xnumber, degrees0Tilts the model around X, for parts that are not lying flat in CAD.
rotation_ynumber, degrees0Tilts the model around Y.
work_coordinate_system'G54' … 'G59''G54'Work coordinate system selected in the program.

operations — Operations

contourbooltrueCut the outer contour.
inner_contourbooltrueInner contours and cut-outs that are not round holes.
holesbooltrueRound holes.
pocketsbooltruePockets. The depth information for them lives in the STEP geometry; DXF and SVG do not carry it.
pocket_step_overinteger, %50Overlap between clearing passes.
pocket_start_at'Edge' | 'Center''Edge'Clear from the outside in, or from the inside out.
dogboneboolfalseDogbone corners so square counterparts fit into inside corners.
ramp_entrybooltrueEnter on a ramp instead of plunging straight down.
cylindrical_hole_mode'auto' | 'helix' | 'normal''auto'How round holes are made: helical milling, drilling, or decided automatically from diameter and material.
orderlist of stringsemptyCustom operation order, e.g. ["facing","pockets","holes","inner","contour","other"]. Empty means the internal default order.

settings — Job behaviour

holding_tabsbooltrueMaster switch for holding tabs. Their geometry lives in tags.
holding_tabs_outerbooltrueTabs on the outer contour.
holding_tabs_innerbooltrueTabs on inner contours.
ramp_entrybooltrueRamp entry, as in operations.
dogboneboolfalseDogbone corners, as in operations.
optimize_passesbooltrueDistributes the depth over even passes on its own and treats depth.step_down as an upper bound only. Set it to false when the step-down has to be honoured exactly.

tags — Holding tabs

Only takes effect when tabs are enabled through settings.holding_tabs. Empty dimensions mean AUTO: derived from part size and cutter diameter.

enabledboolfalseCreate tabs.
widthnumber, mmempty = AUTOWidth of one tab.
heightnumber, mmempty = AUTOHeight of one tab, usually a fraction of the cutting depth.
lengthnumber, mmempty = AUTOLength of one tab along the contour.
anglenumber, degrees45Flank angle of the tabs.
spacingnumber, mmempty = AUTODistance between two tabs along the contour.

facing — Facing

enabledboolfalseFace the surface before machining.
depthnumber, mm0.5Layer to be removed.
step_overinteger, %50Path overlap.
pattern'ZigZag' | 'Offset''ZigZag'Path pattern.
zigzag_anglenumber, degrees0Direction of the zigzag passes.
add_to_depthbooltruetrue: the faced layer is added to the stock thickness. false: it is subtracted from the cutting depth.
extensionnumber, mmempty = half the cutterOvershoot beyond the workpiece edge. 0 turns the overshoot off.

chamfer — Chamfer, engraving and 2D direct mode

enabledboolfalseRun a chamfer with the V-bit.
depthnumber, mm2.0Depth of the chamfer.
hole_depthnumber, mmemptyDifferent chamfer depth at holes. Empty means: same as depth.
engravingboolfalseEngraving mode: follows the contour without cutter radius compensation, even with a flattened tip.
dxf_directboolfalse2D direct mode: G-code straight from the DXF paths, without going through an extrusion.
controller_compensationboolfalseLeave radius compensation to the controller (G41/G42) instead of baking it into the path.

vshape_adaptive — V-carving

enabledboolfalseV-carving with adaptive depth instead of a constant chamfer depth.
max_depthnumber, mm0 = unlimitedUpper bound for the carving depth.
depth_stepnumber, mm0.5Depth increment per pass.
nesting_mode'inner' | 'outer''inner'Contour selection: carve inside the inner contours, or clear the outer areas and leave holes out. Not to be confused with arranging several parts.

laser — Laser

enabledboolfalseLaser job instead of a milling job.
powernumber, %100Power.
speednumber, mm/min1000Speed.
passesinteger1Number of passes.
mode'cut' | 'engrave''cut'Cutting or engraving.
kerfnumber, mm0Kerf width the path is offset by.
kerf_enabledboolfalseSwitches the compensation on. Without this flag kerf has no effect.
nesting'all' | 'outer' | 'inner''all'Contour selection: all contours, outer only, or inner only.

postprocessor — Output format

GET /api/postprocessors returns the full list of names.

namestring'grbl_post'Controller dialect, e.g. grbl_post, linuxcnc_post, mach3_mach4_post, uccnc_post, marlin_post, fanuc_post, heidenhain_post, estlcam_post.
custom_preamblestringemptyYour own G-code lines before all operations.
custom_postamblestringemptyYour own G-code lines after all operations.

Verification stays your job

The generated G-code is a machine-produced proposal. Verify tool paths, depths of cut, feed rates and clearances before every run, and do an air pass without a workpiece when in doubt. Uploaded files are deleted after 24 hours at the latest.

Frequently asked questions

How do I authenticate?

With the access token from your credit purchase, as the header Authorization: Bearer YOUR-TOKEN. If that header is already taken — behind some corporate proxies or an upstream basic auth — use X-Api-Token: YOUR-TOKEN instead. Both are equivalent.

What happens without credits?

Upload and generation still work; the download responds with status 402 and the reason no_credits. An invalid token is rejected at upload time with 401 and invalid_token.

Which settings can I pass?

The same ones the interface offers, as a nested object. Every field with its type, default and effect is listed above under "Every parameter of POST /api/generate" — each block is optional, whatever you leave out keeps its default. Three traps are worth knowing: depth.step_down only acts as an upper bound while settings.optimize_passes is true; laser.kerf additionally needs kerf_enabled; and a material name sets no cutting data, that comes from tool or feed_rates.

Are there limits?

Yes, a rate limit per IP address so the service stays available for everyone. A valid access token raises the limit. Bulk requests without a token are not permitted under the terms of service.

How long do jobs stay available?

Uploaded files and results are deleted after 24 hours at the latest, and a service restart can invalidate job ids earlier. So download the G-code promptly.

What if I would rather let an assistant drive it?

Then use the MCP server: it sits on this same interface and turns it into tools for Claude, ChatGPT, the Gemini CLI and other clients.

MCP server: the same interface inside an AI assistant