Skip to main content
The Instructions API lets agents and integrations maintain the same rich, nested manuals that people edit in OpenTrain. The canonical format is versioned TipTap JSON; page-content and tree mutations travel through atomic changesets, and every publication is an immutable snapshot. Base path:
Send Authorization: Bearer ot_pat_… on every request. Start with GET /capabilities so your client uses the current schema vocabulary and limits. The complete machine-readable contract is also available in the OpenAPI document.

Scopes and roles

Token scopes and workspace roles are both enforced. A token never grants access to a workspace the user cannot access. Workspace creation persists an OWNER permission record for the creator. Owners can grant EDITOR, REVIEWER, or VIEWER access to other users. See Scopes and capabilities for token creation and least-privilege guidance.

Endpoint map

All paths below are relative to the base path.

Discovery, workspaces, and permissions

Create a workspace with {"name":"Operations"}. Grant access with {"principalId":"<userId>","role":"REVIEWER"}.

Manuals, trees, and pages

Manual bindings are {kind,targetId,precedence} objects. kind is JOB, FOLDER, or WORK_PROJECT; lower precedence wins among bindings of the same specificity. A manual body is not edited through PATCH /manuals or PATCH /pages—content and tree mutations always use changesets. GET /pages/{pageId} accepts revision and format=json|html|markdown. Markdown responses include a loss report; canonical JSON is always returned so clients never depend on a lossy representation.

Atomic changesets and review

Validate, diff, apply, and submit share one body:
Changesets support PATCH_CONTENT, explicitly confirmed REPLACE_CONTENT, CREATE_PAGE, RENAME_PAGE, MOVE_PAGE, SET_AUDIENCE, ARCHIVE_PAGE, RESTORE_PAGE, and ATTACH_ASSET. Node patches support replace_node, insert_before, insert_after, append_children, set_attrs, and delete_node. Use a clientPageKey on CREATE_PAGE and refer to the new parent as new:<clientPageKey> to create a nested section in one request. Operation order does not matter.
Whole-document replacement requires confirmReplace: true. Prefer stable-node patches so concurrent edits to unrelated blocks can be rebased safely.

Conflicts and idempotency

Revision, checksum, node, tree, schema, and asset conflicts are structured:
Possible conflict codes include REVISION_MISMATCH, CHECKSUM_MISMATCH, NODE_NOT_FOUND, PAGE_NOT_FOUND, MANUAL_NOT_FOUND, PARENT_NOT_FOUND, PAGE_ARCHIVED, DEPTH_EXCEEDED, TREE_CYCLE, DUPLICATE_CLIENT_KEY, AUDIENCE_INVALID, ASSET_NOT_READY, SCHEMA_INVALID, and REPLACE_NOT_CONFIRMED. Send a stable Idempotency-Key for creates, applies, submits, restores, and publications. Retrying the same request returns the original result; reusing the key with a different body returns 409.

Revisions and restoration

Publications

Publish with {"baseRevisionNumber":7,"audiences":["WORKER","REVIEWER"],"note":"First release"}. Audience values are ADMIN, CONTRIBUTOR, REVIEWER, and WORKER.

Private assets

Prepare accepts workspaceId, filename, mimeType, sizeBytes, sha256, and optional kind (IMAGE, FILE, AUDIO, or VIDEO). Upload the bytes to the returned URL with the returned headers, then finalize. Canonical documents reference asset IDs, never storage URLs.

Search and rendering

Render preview accepts either {pageId,revisionNumber?,format} or {content,format}. format is html or markdown; Markdown always includes a machine-readable loss report.

Error envelope

Transport and permission failures use the standard API error shape:
Expect 400 for malformed requests or canonical documents, 403 for missing token scopes or workspace permission, 404 for inaccessible resources, and 409 for revision, checksum, tree, node, or idempotency conflicts.

Next steps