Skip to content

WordPress REST API: Everything I Ship to This Blog Goes Through It

The editor is a convenience. The API is the interface. What actually broke running this blog through the WordPress REST API, and what the fix was.
WordPress REST API featured card: the API is the interface

Technology

I have not opened the WordPress block editor on this site in months. Every post here, including this one, was written, styled, given its metadata and published through the REST API by a process that runs on a schedule while I am asleep.

The editor is a convenience. The API is the interface.

That is not a flex about automation. It is a structural choice. A publishing step you can only perform by hand is a step that stops the week you get busy, and the weeks you get busy are the weeks the publishing matters most.

WordPress ships a full REST API at /wp-json/wp/v2/. Posts, media, categories, metadata, all of it. What follows is not the documentation. It is what actually broke, in production, on this blog, and what the fix turned out to be.

Why publish through the API instead of the editor?

Because a process that runs without you has to be callable, and a user interface is not callable.

The editor is built for a person sitting in front of it making one decision at a time. That is the right tool for a person. It is the wrong tool for a system that has to assemble a post from a brief, set five metadata fields, build and upload a featured image, attach it, and publish, at an hour when nobody is at the keyboard.

The same reasoning that puts my automation layer on a server I control rather than a per-task platform applies here. An interface you own cannot be repriced, redesigned or deprecated out from under your workflow.

How does authentication actually work?

Cookie authentication plus a nonce, if the code is already running inside a logged-in session.

WordPress exposes window.wpApiSettings.nonce on every admin page. Send it as an X-WP-Nonce header on a same-origin request and the API treats you as that logged-in user, with that account’s full permissions. No plugin, no OAuth handshake, no application password.

For anything running server to server, use an application password instead. A nonce is short-lived by design and will expire in the middle of a long run. Pick the method that matches where the code lives, not the one that is faster to paste.

What breaks first?

Time. Not the API.

Every integration has a ceiling somewhere, and the useful work is finding yours deliberately instead of meeting it during a live run. On this setup the ceiling is an execution limit of roughly forty five seconds per call. Three sequential two megabyte image uploads do not fit inside it. Two do. So the rule became two uploads per call, not because two is elegant, but because three fails.

Every integration has a ceiling. The work is finding yours on purpose, before it finds you in production.

The second thing that breaks is asynchrony. A backgrounded browser tab gets throttled, and fetch, await and setTimeout all die quietly inside it. Synchronous XMLHttpRequest does not. The modern API is the wrong one here, which is an uncomfortable sentence to write and a true one.

The third is subtler and cost a full run to isolate. Fetching an image and posting it to the media endpoint inside the same call throws a network error at around six hundred kilobytes. Split the fetch and the upload into two separate calls and it works every time. Same bytes, same endpoint, different shape.

Why does media need its own method?

Because /wp-json/wp/v2/media does not take JSON. It takes the raw bytes of the file with a Content-Disposition header naming it.

That is a different request shape from everything else in the API, and it is where most integrations stall. Build the binary as a typed array, set the header, send it, read the id out of the response. Alt text goes up in a follow-up call, because the upload response is not where it belongs.

Attaching it is another step again. featured_media on the post takes the media id, never the URL. A post can carry a perfectly good image in its body and still have no featured image, which is exactly how a blog grid ends up full of grey boxes.

Can you set the SEO fields too?

Yes, and almost nobody does.

Yoast registers its fields in post meta, which means the SEO title, the focus keyword and the meta description all go up with the post in the same request. One call, every field set, no second pass through a plugin screen. That alone removes the step most publishing automations quietly skip.

There is one trap in it. Setting featured_media through the API updates the post but not Yoast’s stored indexable row, so the og:image keeps pointing at the previous file. The page looks right and the share card is wrong. The fix is a second request to the same endpoint sending featured_media again alongside empty opengraph image fields. Purging the page cache does nothing, because it was never a cache.

Slugs are safer than people assume. WordPress writes the previous slug to post meta and redirects the old URL automatically, so renaming a post onto a better head term costs nothing. What is not safe is deleting and recreating the post, which breaks that chain and throws away whatever the old address had earned.

The request that succeeded and timed out anyway

This is the one worth internalising, and it is not really about WordPress.

A call that hits the execution limit has not necessarily failed. More often it reached the server, did the work, and returned a response the client was no longer listening for. Retry it blind and you get two media items, or two posts, or two charges. The automation looks fine and the data is wrong.

A timeout is not a failure. It is an answer you stopped waiting for.

So the retry rule is: query the state first, assume the first attempt worked, and only act when the evidence says otherwise. Write that into the job rather than into your memory. The model rarely breaks, the handoff does, and this is a handoff.

None of this is exotic. It is the plumbing of one website, written down. It is worth writing down because the plumbing decides whether a publishing habit survives a busy month, and a habit that survives is worth more than any single post it produces.

Cody Wise at a multi monitor home office workstation, the desk where this blog is published from
Own the interface and the tool becomes a detail. Rent the interface and the tool sets the terms.

Common questions

Can you publish a WordPress post entirely through the REST API?

Yes. A single POST to /wp-json/wp/v2/posts with title, content, status and categories creates and publishes the post. Media, the featured image and the SEO meta fields are separate calls against the same API, so a full post can ship without the editor ever being opened.

How do you authenticate with the WordPress REST API?

Inside a logged-in browser session, send the nonce from window.wpApiSettings.nonce as an X-WP-Nonce header on a same-origin request. For server to server integrations use an application password instead, because a nonce expires and will fail partway through a long job.

Why do WordPress REST API image uploads fail?

Usually time, not permissions. Large sequential uploads exceed the execution limit of the environment making the call, and fetching an image then posting it in the same call can throw a network error at a few hundred kilobytes. Split the fetch and the upload into separate calls and cap the number of uploads per call.

Can you set Yoast SEO fields through the REST API?

Yes. Yoast registers its fields in post meta, so the SEO title, focus keyword and meta description can be set in the same request that creates the post. Setting the featured image this way does not refresh the stored og:image, which needs a second request with the opengraph image fields cleared.

Is it safe to change a post slug through the REST API?

Yes. WordPress stores the previous slug and redirects the old URL automatically, so a rename keeps its link equity. Deleting and recreating the post instead breaks that redirect and loses whatever the old address had earned.

X (Twitter)
LinkedIn
Facebook
WhatsApp

Keep Reading

Reading Is Free. Execution Is The Job.

If one of these frameworks fits the problem you have right now, send a message and we will apply it to your business instead of a hypothetical one.