CFPressbeta

Write API

Write API

Everything the admin does goes through HTTP, so anything the admin can do, a script can do. Authentication is a single header:

X-Auth-Key: <AUTH_KEY_SECRET>

Set the secret once with wrangler secret put AUTH_KEY_SECRET. Requests without a matching key get a 401.

Run SQL in batches

POST /d1-batch executes a list of prepared statements against D1 and returns each result set in order.

curl -X POST https://example.com/d1-batch \
  -H "X-Auth-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "statements": [
      { "sql": "SELECT slug, title FROM posts WHERE status = ? LIMIT ?", "params": ["published", 5] }
    ]
  }'

Up to 200 statements per call. The whole batch is not atomic — statements run in order, and the first failure returns { "success": false, "error": "...", "index": N } so you know exactly which one broke.

This is the same channel the WordPress plugin uses, and it is the simplest way to script a bulk import.

Delete pages

POST /delete removes objects from R2 and invalidates the matching pages.

curl -X POST https://example.com/delete \
  -H "X-Auth-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{ "paths": ["/old-post/index.html", "/old-post/index.html.gz"] }'

Deleting a single page's HTML does not lose data: the post still exists in D1, so the next request re-renders it into R2 from the current template. That is the supported way to force a rebuild without touching content.

Purge caches

POST /purge-cache clears edge cache entries by key or prefix — useful after changing a menu or a theme, where the HTML is cached but the data did not change.

curl -X POST https://example.com/purge-cache \
  -H "X-Auth-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{ "keys": ["home:page:1"], "prefixes": ["category:", "tag:"] }'

WordPress-compatible endpoints

A subset of the WordPress REST write API is available under /wp-json/wp/v2/ (and /wp/v2/), authenticated with application passwords. This exists so editors that already speak the WordPress API — an Obsidian plugin, a publishing script, a mobile client — can publish without custom code.

The supported subset is deliberately small: creating and updating posts, and reading the taxonomies they need. For anything else, use /d1-batch directly.

Rate limits

The key-authenticated channels are rate limited per source IP. A leak of the key therefore does not turn into an unbounded bill; sustained abuse is throttled before it reaches D1.