Editing Docly documents programmatically Last updated: 04. Sep 2026

How to safely create and edit Docly documents from outside the Docly UI — with the docly CLI, a mapped WebDAV drive, scripts, AI coding agents, or any other external tool.

Why this matters

Docly workspaces can be mapped as a WebDAV drive (see Using Claude Code Directly on a Mapped Docly Drive). Once mapped, 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. The drive enforces that binding, and getting it wrong leaves you with an unregistered file that won't open as a document.

Two routes: the docly CLI, or the mapped drive

There are two ways in from outside the UI, and the rest of this page reads differently depending on which one you are using.

  • The docly CLI talks to the server directly. It has no filesystem abstraction, so none of the drive-specific behaviour below applies to it: no redirector cache, no stale file sizes, no Move-Item trap. It also 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.
  • The mapped WebDAV drive makes the workspace look like ordinary files, which is what you want for interactive editing and for opening the workspace in an editor.

For scripts and AI coding agents, prefer the CLI. 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 — are identical either way. Only the mechanics of getting the bytes to the server differ.

The drive has a set of failure modes worth knowing before you choose it: The site drive is WebDAV not a disk, False write-verification failures on the WebDAV drive and Writing a docly file to the drive is an import not an edit. Everything from here on describes the drive route.

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. The drive rejects writes to .docly and .json files when the result is not parseable, so there is no way to leave a file temporarily invalid between edits. 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 — or build the new content in a temp folder and overwrite the file with a copy.

Creating a new .docly file

A direct write works. Write the complete .docly file to the drive path and the drive parses it, reads the Schema string and registers the document. Measured 2026-08-25 against a live site, for a 560-byte document and for a 355 KB one carrying two embedded images.

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.

Building the file in a temp folder and copying it into place is still a good habit and costs nothing — it keeps partial writes off the drive entirely — but it is belt-and-braces rather than a requirement:

  1. Build the complete file in a temp folder outside the Docly drive — somewhere on your local disk. Get the JSON fully correct first, with no partial writes.

  2. Copy the file into the Docly drive in one operation. The drive sees a complete file appear at a .docly path, parses it, looks up the schema, and registers the binding atomically.

  3. Verify the size on the destination. The drive normalizes the file and adds metadata, so the destination file is slightly larger than the source. A destination file that is only 2 bytes means the registration did not happen — correct the file and write the same path again.

  4. Delete the temp source.

Concrete example in PowerShell:

# 1. Build the complete file in temp
$temp = "$env:TEMP\My new doc.docly"
Set-Content -LiteralPath $temp -Value $jsonContent -Encoding UTF8

# 2. Copy (NOT move) into the drive
Copy-Item -LiteralPath $temp `
          -Destination "L:\Websites (Example)\my-site\My new doc.docly"

# 3. Verify size on destination > source
# 4. Clean up
Remove-Item -LiteralPath $temp

Creating one with the CLI instead

The single-document update command only updates an existing document. To create one, clone the destination folder, write the file into the working copy, and push it naming the schema. 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.

docly clone <folder> work && cd work
# write "My new doc.docly" into the working copy, complete and valid
docly status
docly push --schema "<schema-name>" --dry-run
docly push --schema "<schema-name>"

Measured 2026-09-04 against a live site: a pushed document gets its Guid assigned and its Created and Modified stamped by the server, exactly as a drive write does. 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.

Why not Move-Item?

If you do use the temp+copy pattern, copy — do not move. Move-Item (or mv on Unix-like systems) seems like the natural choice, but it fails: when the move begins, the drive sees the destination path and pre-creates a 2-byte placeholder, and the actual file move then fails with The file exists.

Use Copy-Item, then remove the source as a separate step. The leftover placeholder is not fatal — write the complete file to that path and it registers — but it is an avoidable detour.

How to tell if registration succeeded

  • File size: the destination is larger than the source by a few hundred bytes — that is metadata the drive added. A 2-byte file means failure.

  • Directory listing: correctly registered files show with the .docly suffix. Files shown without the suffix have not been registered as documents.

  • 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

If the agent uses the docly CLI, none of the temp+copy mechanics below apply. Point it at How an AI agent should use the docly CLI instead: 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.) to work over the mapped drive, 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.