Generating code
Propose, never deploy.
POST /projects/{id}/generate asks the assistant to produce or modify PLC logic and returns a reviewable proposal. It requires ai_generate and creates no version — generating and persisting are two separate scopes by design.
The two-scope safety boundary
ai_generate drafts; code_write persists. A generate-only key can draft a change but can never deploy a machine-bound version. To apply a proposal, save it as a new version via POST /projects/{id}/versions — generate → human review → commit.
Response
generated_code— the assistant's full markdown answer: prose + fenced```ladder/```st/```sclblocks + inline insertion directives.code_blocks— those fenced blocks lifted out ({ language, content }) for programmatic use.citationsandusage— as with interpret.
An optional target: { program?, routine? } hints at placement. Set "mode": "stream" for an SSE stream (see Streaming).
gen = client.generate(
"prj_…",
"Add a 5-second start-up delay timer before the conveyor enables.",
)
print(gen.generated_code)
for block in gen.code_blocks:
print(block.language, block.content)var gen = await client.GenerateAsync(
"prj_…",
"Add a 5-second start-up delay timer before the conveyor enables.");
Console.WriteLine(gen.GeneratedCode);
foreach (var block in gen.CodeBlocks)
Console.WriteLine($"{block.Language}: {block.Content}");Generate is a write (it runs the model): it requires an Idempotency-Key, and a replay returns the stored proposal without a second model run. It honors the org's API spend cap — a paused org gets 402.