The WordPress REST API: What Publishers Need to Know
The WordPress REST API has been part of WordPress core since version 4.7. It transforms WordPress from a self-contained CMS into a content platform that can serve data to any application that can make an HTTP request — mobile apps, static front ends, third-party services, or another WordPress site. For publishers evaluating headless architecture or building integrations, understanding what the API provides (and how to use it) is increasingly essential.
What the REST API Exposes
By default, the WordPress REST API exposes endpoints for every major content type. All endpoints are accessible under the /wp-json/wp/v2/ base path.
Posts: GET /wp-json/wp/v2/posts returns a paginated list of published posts with full metadata. Individual posts are accessible at /wp-json/wp/v2/posts/{id}.
Pages: GET /wp-json/wp/v2/pages — same structure as posts.
Categories and Tags: /wp-json/wp/v2/categories and /wp-json/wp/v2/tags return taxonomy term lists.
Media: /wp-json/wp/v2/media returns media library items with URLs, MIME types, and attachment metadata.
Users: /wp-json/wp/v2/users returns public author data (display name, avatar URL, description).
Custom Post Types: Registered with show_in_rest: true are automatically exposed at their own endpoints.
Querying the API
The API accepts query parameters for filtering, sorting, and pagination.
Filter by category:
GET /wp-json/wp/v2/posts?categories=5
Filter by tag:
GET /wp-json/wp/v2/posts?tags=12
Search:
GET /wp-json/wp/v2/posts?search=publishing
Pagination:
GET /wp-json/wp/v2/posts?per_page=20&page=2
Ordering:
GET /wp-json/wp/v2/posts?orderby=date&order=desc
Filtering fields returned (reduces response size):
GET /wp-json/wp/v2/posts?_fields=id,title,excerpt,slug,date,_links
The _fields parameter is useful for performance — a full post response includes the rendered content, raw content, metadata, and embedded link data. If you only need titles and slugs for a listing page, specifying fields reduces bandwidth and parse time.
Embedding related data:
GET /wp-json/wp/v2/posts?_embed
The _embed parameter inlines author data, featured media, and taxonomy terms into the post response, eliminating the need for separate API calls to resolve these relationships.
Authentication
Public, published content requires no authentication. For creating, updating, or deleting content — or accessing draft and private posts — authentication is required.
Application Passwords (WordPress 5.6+) are the standard approach for server-to-server integrations. Generate an application password under Users → Your Profile → Application Passwords in the WordPress admin. Include it as a Basic Auth header:
const response = await fetch('https://yoursite.com/wp-json/wp/v2/posts', {
headers: {
'Authorization': 'Basic ' + btoa('username:application-password')
}
});
For user-facing web applications where users log in to a WordPress account, use OAuth or cookie-based authentication (the latter requires the request originate from the same domain).
Creating Content via the API
Authenticated POST requests create new content:
const newPost = await fetch('https://yoursite.com/wp-json/wp/v2/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('username:app-password')
},
body: JSON.stringify({
title: 'Post Title',
content: '<p>Post content in HTML.</p>',
status: 'draft', // or 'publish'
categories: [5],
tags: [12, 15],
excerpt: 'Custom excerpt text.'
})
});
const post = await newPost.json();
console.log(post.id, post.link);
This enables automated publishing workflows — populating WordPress from external content sources, pushing content from a writing tool to WordPress without using the admin, or building custom editorial interfaces that write back to WordPress.
Custom Post Types and Meta
To expose a custom post type through the REST API, register it with show_in_rest enabled:
register_post_type('press_release', [
'public' => true,
'show_in_rest' => true,
'rest_base' => 'press-releases',
'supports' => ['title', 'editor', 'custom-fields'],
// other args...
]);
Custom fields (post meta) require explicit registration to appear in REST responses:
register_post_meta('press_release', 'distribution_date', [
'show_in_rest' => true,
'single' => true,
'type' => 'string',
]);
Practical Use Cases for Publishers
Headless front end. Build a Hugo, Next.js, or Astro front end that fetches content from WordPress via the API at build time. Editors use the familiar WordPress admin; the front end is a separately deployed static or server-rendered application.
Mobile app. A native iOS or Android app that displays WordPress content through the REST API, with optional write-back for user-generated content.
Cross-site syndication. Pull content from one WordPress installation into another, or feed content to a syndication partner, through scheduled API queries.
Content migration. Export content from WordPress in structured JSON format for migration to another CMS or for archival.
Custom editorial tools. Build a specialized editing interface (a distraction-free writer, a structured data form, a bulk editing tool) that reads and writes content through the API.
Limitations and Alternatives
The REST API’s performance under heavy traffic is bounded by WordPress’s PHP and database layer. For high-traffic applications that query the API on every request, caching the API responses (through a CDN or application cache) is essential.
For more complex querying requirements — fetching deeply nested content relationships, querying across multiple post types efficiently — the WPGraphQL plugin provides a GraphQL endpoint that is more flexible than the REST API for complex data retrieval patterns.