Skip to content

Edit

Read and change a project's files.


How Editing Works

Any file in a project can be changed: pages, data, manifest.json, styles, images, and more. Each update becomes a new deployment on staging, so you can check it before you promote it.

To start from nothing, publish a build, or send an update that includes an index.html. For a documentation site from Markdown, the Docs Template builds one in a single request.


Read Files

List the files of the live deployment, so you can see what to change.

curl "https://api.manifestx.dev/v1/projects/proj_…/files?env=staging" \
  -H "Authorization: Bearer $MANIFEST_ACCOUNT_KEY"
Field Type Required Notes
env string no staging (default) or production.
limit number no Files per page, 1 to 1,000. Defaults to 1,000.
cursor string no The next_cursor from the previous page.
{
  "env": "staging",
  "deployment_id": "dep_…",
  "files": [
    { "path": "_redirects", "size": 64, "content_type": "application/octet-stream", "etag": "9b2e…" },
    { "path": "_redirects.json", "size": 210, "content_type": "application/json; charset=utf-8", "etag": "41c7…", "compiled_from": "_redirects" },
    { "path": "articles/intro.md", "size": 1834, "content_type": "text/markdown; charset=utf-8", "etag": "e3b0…" },
    { "path": "index.html", "size": 2210, "content_type": "text/html; charset=utf-8", "etag": "5d41…" }
  ],
  "next_cursor": null,
  "request_id": "…"
}
  • Paths match what a file update takes, sorted by path.
  • etag changes when a file's content does. Treat it as opaque: the same content can carry a different etag if published another way.
  • compiled_from marks a file Manifest compiles. Edit the source file instead.
  • Left out: precache.json and manifest.utilities.css, which Manifest writes on every publish.
  • Nothing live yet: deployment_id is null and files is empty.
  • More pages: send next_cursor as cursor. A cursor keeps reading the same deployment, even if a new one goes live meanwhile.

Read One File

Fetch one file's content from the deployment live on env (staging by default).

curl "https://api.manifestx.dev/v1/projects/proj_…/files/articles/intro.md" \
  -H "Authorization: Bearer $MANIFEST_ACCOUNT_KEY"

The answer is the file itself, not JSON, with these headers:

Header Value
Content-Type The file's type, such as text/markdown; charset=utf-8 or image/png.
ETag The file's etag from the list, in quotes.
x-manifest-deployment The deployment the file came from. Send it as base with your update.

HTML comes back as stored, without the tags Manifest adds when serving. Send If-None-Match with the ETag to get 304 Not Modified when nothing changed. Encode special characters in the path the way a browser would, such as a space as %20.


Update Files

When only a few files change, send just those. Manifest keeps everything else that is live on staging and publishes the result as a new staging deployment.

curl -X PATCH https://api.manifestx.dev/v1/projects/proj_…/files \
  -H "Authorization: Bearer $MANIFEST_ACCOUNT_KEY" \
  -H "Idempotency-Key: edit-intro-0042" \
  -H "Content-Type: application/json" \
  -d '{
    "base": "dep_…",
    "files": [
      { "path": "articles/intro.md", "content": "# Introduction\n\nUpdated text." },
      { "path": "media/logo.png", "content_base64": "iVBORw0KGgo…" },
      { "path": "articles/old.md", "delete": true }
    ]
  }'
Field Type Required Notes
files array yes 1 to 1,000 changes, one per path.
base string no The deployment your changes start from. If staging has moved on since, nothing changes and the answer is 409 base_mismatch.
env string no Only staging. Promote to reach production.

Each change has a path from the project root (inside output_dir, if the build has one) and exactly one of these:

Field Type Notes
content string The new file as UTF-8 text, for Markdown, JSON, HTML, CSS, and other text files.
content_base64 string The new file as standard base64, for images and other binary files.
delete boolean true removes the file.

A path that doesn't exist yet adds a file. The answer is 201 Created, and the new version is live on the staging URL straight away:

{
  "deployment": { "id": "dep_…", "env": "staging", "status": "ready", "files": 43, "bytes": 320544, "base": "dep_…" },
  "changes": { "updated": 2, "deleted": 1 },
  "url": "https://acme-docs-staging.manifestx.ai",
  "request_id": "…"
}

Avoid Overwriting Others

Send the last deployment.id you saw as base, so two editors can't overwrite each other.

  1. Read the files and note the deployment_id.
  2. Send your update with that id as base.
  3. On 409 base_mismatch, read the files again, reapply your change, and send it with the new live_deployment_id.

Without base, changes apply to whatever is live on staging. Either way, an update is refused with the same 409 if another publish lands while it runs, and you can send it again.

Good to Know

  • Limits. A request can be up to 12 MB, with each file up to 8 MB after decoding. Publish larger files in a zip.
  • First publish. If nothing is live on staging yet, the files become the project's first version and must include index.html. No update can remove index.html.
  • Refused paths. .env files, .git, node_modules, .claude, precache.json, and manifest.utilities.css are refused.
  • Redirects and headers. Manifest compiles _redirects and _headers into .json files. Update the source file, not the compiled one.
  • HTML read back is fine. The analytics and badge tags Manifest adds when serving a page are removed before the file is stored.
  • Prerendered builds. On render output, the answer carries a prerendered_site notice: pages built from the changed files aren't rebuilt, so publish a new build to refresh them.
  • It counts as a publish. Each update counts toward a Free project's daily publish limit. It's also a new deployment, so frequent updates push older versions out of rollback reach.
  • A rare warning. If a follow-up step doesn't finish, the answer is still 201 with a warning. Don't resend it: the step completes on the next publish.