Editing Docly documents programmatically Last updated: 24. Oct 2026
How to safely create and edit Docly documents from outside the Docly UI — with the docly CLI, scripts, AI coding agents, or any other external tool.
Why this matters
With a docly CLI working copy you can edit files with any tool — VS Code, scripts, IDE plugins, or AI coding agents like Claude Code or Cursor.
Most files behave like ordinary files. But .docly documents are different — they are JSON files bound to a Docly schema at creation time. Docly enforces that binding, and getting it wrong leaves you with an unregistered file that won't open as a document.
The docly CLI
The docly CLI talks to the server directly. It gives you a working copy and a line-level diff before anything is public, and it refuses to write at all until someone has explicitly opened one folder for writing.
Run docly with no arguments for the complete command reference, and see How an AI agent should use the docly CLI for how an agent should work with it.
The document rules — the envelope, exact field names, internal enum values rather than labels, flattened chapters — apply to every write from outside the UI.
Editing an existing .docly file
Editing an existing document is straightforward — open the file, change the JSON, save. The schema binding is already in place and survives in-place writes.
Every save must be valid JSON. An unparseable .docly file is stored as a plain text file (Code File) under the same name, and that REPLACES the document: it gets a new id, and its shares, publications and links to the old id are lost. docly push refuses such a replacement unless you pass --allow-replace; docly put performs it and prints the new id. If a refactor would break the JSON mid-way (e.g. removing one element and adding another in separate steps), do the whole change in a single edit.
With docly edit, the same rule applies to the replacement text. edit replaces text in the document exactly as docly get shows it, and for a .docly document that is the JSON file. A quote or backslash in the new text must therefore be written escaped — \" and \\ — just as it appears in the file. Older servers committed an edit that broke the JSON: the document was replaced by a Code File with a new id, the page answered 404, and the command still reported success. Servers with the fix refuse such an edit with result code 27 and leave the document untouched, and refuse any other edit that would replace the document instead of changing it with code 24.
Creating a new .docly file
Write the complete file. Docly parses the .docly file, reads the Schema string and registers the document.
A failed write does not burn the filename. This page previously said it did; that is wrong. Both failure shapes were tested at the same path and then corrected at that same path: truncated JSON leaves the file on disk unregistered, and writing valid JSON afterwards registers it normally; a Schema value naming a schema that does not exist registers the document with that string verbatim, and rewriting the same path with the correct name binds it correctly. So the reason to get the JSON right is that an unparseable or unbound document is useless — not that the name is spent. Details in Creating new docly files.
There are two ways to create a document with the CLI. For one document, docly put <folder path>/<name>.docly <file> --create creates it server-direct. To review first, clone the destination folder, write the file into the working copy and push it. Either way the schema comes from the Schema field in the envelope — there is no schema flag. The document is sent in one request, so the server never sees a partial file, and docly status and docly diff let you look at it before it is public.
# One document, server-direct:
docly put "/<site>/<folder>/My new doc.docly" my-new-doc.docly --create
# Or with review first:
docly clone <folder> work && cd work
# write "My new doc.docly" into the working copy, complete and valid, with "Schema" set
docly status
docly push --dry-run
docly push Measured 2026-09-04 against a live site: a pushed document gets its Guid assigned and its Created and Modified stamped by the server. Tags supplied in the envelope survive, and come back reordered — they go through the database rather than being echoed from the file. A later push that updates the document leaves Created untouched.
How to tell if registration succeeded
Read it back:
docly get <reference> --rawprints the stored value with its envelope. Check thatSchemais the one you set.Open the document: in Docly it should open with the right schema-driven editor or render correctly on the web. If it opens as raw text or an upload, registration failed.
Recovering from a misregistration
Correct the file and write the same path again. A document that did not register, or that registered against a schema name that does not exist, is fixed in place: fix the JSON or the Schema value and write it to the same path. There is no cached binding to clear and no need for a new filename.
Earlier versions of this page said a failed first write burned the filename for good and that recovery meant picking a new name or deleting the file through the Docly UI. That was measured to be wrong on 2026-08-25 — see Creating new docly files. If you have an old .claude/CLAUDE.md or agent skill repeating the one-shot rule, correct it: agents avoid perfectly good filenames because of it.
Notes for AI coding agents
Point the agent at How an AI agent should use the docly CLI: that article is written to be handed to an agent directly and covers what the command reference cannot — that writing is locked until a human opens a folder, that a refused write means stop and ask, and that changes are verified from the site console and the system log.
If you are configuring an AI coding agent (Claude Code, Cursor, etc.), drop a .claude/CLAUDE.md (inside the .claude folder, not the workspace root - the root is published and served over HTTP) telling it to write the complete file in one operation and to verify registration afterwards. Do not tell it the filename is one-shot: that claim is wrong, and an agent that believes it will silently rename around a file it could simply have rewritten.
For how to structure those instruction files across a workspace, see Set up AI agent instruction files for a workspace.
Rule of thumb: write the complete file in one operation, then verify it registered. If it did not, fix it and write the same path again.