instructions:read and either instructions:write (direct authoring) or instructions:propose (reviewed proposals). Proposal authors need workspace EDITOR or OWNER; reviewer decisions need instructions:review plus REVIEWER or OWNER. Publishing needs instructions:publish plus OWNER. See scopes.
1. Discover the vocabulary
Fetch the schema contract once and cache it — it tells you every valid node type, mark, attribute, operation, audience, and asset limit:2. Create a workspace and manual
3. Author nested pages in one atomic changeset
Give eachCREATE_PAGE a clientPageKey, then reference it from children as new:<key> — order doesn’t matter, and the whole section lands atomically or not at all:
4. Edit content with stable-node patches
Read a page (GET /pages/{pageId}) to get its canonical JSON, revision, and per-block attrs.id values, then patch specific blocks:
REVISION_MISMATCH conflict with the current revision — re-read, rebase your patch, retry. Run the same body through /changesets/validate first when you want a dry run.
5. Attach private media
ATTACH_ASSET operation. Documents reference assets by ID only; readers get short-lived signed URLs. Finalization checks the prepared object and trusted upload metadata, but it does not independently download and re-hash the stored bytes; keep your local SHA-256 as the source integrity check.
6. Propose, review, publish
On a shared manual, anEDITOR or OWNER can submit instead of applying: POST /changesets/submit stores the proposal and returns a review URL. A REVIEWER or OWNER approves or rejects it (optionally with a decisionNote), and the approved proposal is applied by ID — still revision-guarded, so stale proposals conflict instead of clobbering newer edits.
When the manual is ready for workers:
Prefer files? Use the CLI’s docs-as-code loop
opentrain instructions checkout materializes a manual as local JSON files with a manifest of revisions and checksums; edit, status/diff, then sync pushes your changes back as one guarded changeset. See the CLI reference.