
Every modern WordPress install ships with a REST API that lets you read and write content over HTTP, without touching PHP or the database directly. It is the same interface the block editor uses behind the scenes, and it is stable enough to build real integrations on: import scripts, mobile app backends, headless frontends, or simple automation between WordPress and other services. This tour covers the shape of the API, how to authenticate safely with application passwords, and how to build a tiny end-to-end integration you can adapt.
What the REST API actually is
The REST API exposes WordPress data as JSON over standard HTTP verbs. Posts, pages, users, comments, media, taxonomies, and most custom post types are all available under a consistent URL pattern rooted at /wp-json/. You can confirm it is active on any site with:
curl https://example.com/wp-json/That returns a discovery document listing available routes and namespaces. Core content lives under the wp/v2 namespace, so posts are at /wp-json/wp/v2/posts, pages at /wp-json/wp/v2/pages, and so on. Plugins and themes can register their own namespaces and routes, which is why the discovery document is worth checking on any given site rather than assuming a fixed list.
Reading data: no authentication required
Public content is readable without any credentials, which makes the API a good first stop for exploration:
curl https://example.com/wp-json/wp/v2/postsThis returns an array of published posts with fields like title, content, date, and link. Add query parameters to filter and shape the response:
curl "https://example.com/wp-json/wp/v2/posts?per_page=5&_fields=id,title,link"The _fields parameter trims the response to only what you need, which matters once you start hitting the API from a script or a frontend rather than a terminal. Single items work the same way with an ID appended to the route, for example /wp-json/wp/v2/posts/42.
Writing data: you need to authenticate
Creating, editing, or deleting anything requires proving who you are. WordPress core supports a few authentication methods, but for server-to-server integrations and command line work, application passwords are the standard choice. They were built into core specifically so plugins would not each need to invent their own auth scheme.
An application password is a randomly generated credential tied to a specific user account and given a label so you remember what it is for. It is separate from the user’s login password, and you can revoke it independently without touching anything else. You can generate one in the dashboard under the user’s profile page, or from the command line with wp-cli:
wp user application-password create admin "REST integration"That command prints a generated password. Store it immediately since WordPress does not show it again. Pair it with the username using HTTP Basic Auth on your requests:
curl -u "admin:xxxx xxxx xxxx xxxx" https://example.com/wp-json/wp/v2/users/meA successful response confirming your own user details means authentication is working. One important detail: WordPress requires HTTPS for application passwords to function outside of localhost, which is one more reason a valid TLS certificate on your origin is not optional. If your site sits behind Cloudflare, Universal SSL covers the edge connection, but make sure your origin certificate is valid too so the full path is encrypted.
Building a tiny integration: create a post from the command line
With an application password in hand, you can create content programmatically. Here is a minimal example that posts a new draft:
curl -u "admin:xxxx xxxx xxxx xxxx" \
-X POST https://example.com/wp-json/wp/v2/posts \
-H "Content-Type: application/json" \
-d '{"title":"Hello from the REST API","content":"Created via curl.","status":"draft"}'The response is the newly created post object, including its id. From here the pattern extends naturally: fetch external data from another system, transform it into the fields WordPress expects, and POST it in. A common real integration looks like this: a script polls an external feed, checks for new items, and creates a draft post for each one with the source content in content and metadata stored in custom fields via meta, if the fields are registered to be visible to the REST API. Editorial staff then review drafts before publishing, which keeps a human in the loop without anyone hand-copying content.
Updating an existing post uses the same route with an ID and a POST request carrying only the fields you want to change:
curl -u "admin:xxxx xxxx xxxx xxxx" \
-X POST https://example.com/wp-json/wp/v2/posts/123 \
-H "Content-Type: application/json" \
-d '{"status":"publish"}'That single call flips a draft to published, which is often the last step in an approval workflow built entirely on the API.
Authentication inside WordPress itself
Application passwords are the right tool for external scripts and services. If you are writing JavaScript that runs inside the WordPress admin or on the frontend of your own site, use the nonce-based approach instead: WordPress can localize a nonce into your script via wp_localize_script, and you send it in an X-WP-Nonce header on same-origin requests. This avoids exposing any password-like credential to the browser at all. Reach for application passwords specifically when the caller is a separate system, a different server, or a script running outside the browser context.
Performance and caching considerations
REST API requests are dynamic by nature and typically bypass full-page caching layers like LiteSpeed Cache, since each request can carry different parameters, headers, or authentication. That is expected behavior, but it means a heavily used REST integration (a mobile app hitting your site constantly, for example) puts load directly on PHP and the database rather than serving from cache. If you are running an integration at meaningful volume, keep an eye on the same fundamentals that matter for the rest of the site: PHP 8.3 with OPcache enabled, and Redis or Memcached for persistent object caching so repeated database queries inside REST callbacks do not hit the database every time. Cloudflare sitting in front of the site still helps with bot mitigation and DDoS protection for these endpoints even though the responses themselves are not edge cached. If you are on managed hosting, this stack is often already configured for you, which is one less thing to tune before your integration goes live.
Takeaway
The REST API gives you a clean, well-documented way to read and write WordPress content without writing custom PHP endpoints. Start by exploring the discovery document and public GET routes, generate an application password with wp-cli or the dashboard when you need to write data, and build outward from a single curl command to a full script. The pattern scales from a one-off automation to a production integration without changing shape, which is exactly what makes it worth learning properly the first time.