Complete WordPress REST API Guide 2026
Learn endpoints, authentication, CRUD operations, and how to build headless CMS with WordPress
Table of Contents
What is WordPress REST API
The WordPress REST API is a bridge that allows external applications (mobile apps, React frontends, or other services) to interact with your WordPress site without touching the Admin Dashboard or writing data through traditional HTML forms. Instead of relying on HTML pages, the REST API communicates using JSON (JavaScript Object Notation) — a lightweight, standardized format for exchanging data between server and client.
REST API was added to WordPress 4.7 in January 2017 and has been part of WordPress core ever since, receiving continuous updates and improvements. Using REST API enables you to build a Headless CMS — separating your Content Management System (backend, used by admins) from your Frontend Presentation (what users see on screen). This separation provides tremendous flexibility and power.
Before REST API, if you wanted a Mobile App to read from WordPress, you had to use XML-RPC, which was cumbersome and slow. Today, REST API allows straightforward HTTP GET requests in JSON, making it much easier to build Mobile Apps, React/Vue frontends, or Next.js sites powered by WordPress as a content backend. The simplicity and ubiquity of REST APIs in modern web development make WordPress a more attractive choice for headless architectures.
Main REST API Endpoints
WordPress REST API follows RESTful standard conventions. All endpoints are prefixed with /wp-json/, followed by a namespace and route. The primary WordPress endpoints are located at /wp-json/wp/v2/, where v2 indicates version 2 of the WordPress REST API.
Core WordPress endpoints include:
/wp-json/wp/v2/posts— Blog posts/wp-json/wp/v2/pages— Static pages/wp-json/wp/v2/categories— Post categories/wp-json/wp/v2/tags— Post tags/wp-json/wp/v2/users— User information/wp-json/wp/v2/comments— Comments on posts/wp-json/wp/v2/media— Attachments and images/wp-json/wp/v2/settings— Site-wide settings
Beyond WordPress core, plugins can register their own endpoints. For example, WooCommerce adds /wp-json/wc/v3/ for e-commerce functions like /wp-json/wc/v3/products to fetch product data. Custom plugins follow similar patterns, creating namespaced endpoints that coexist peacefully.
All endpoints support different HTTP methods (verbs):
GET— Retrieve data (most public endpoints allow this without authentication)POST— Create new data (requires authentication and appropriate permissions)PUT / PATCH— Modify existing data (requires authentication and permissions)DELETE— Remove data (requires authentication and permissions)
Fetching Posts and Pages
Retrieving blog posts from the REST API is the simplest use case — no authentication required, and it can be done from JavaScript running in a browser or from server-side code in any language.
Example: Fetch the 10 most recent published posts:
GET https://example.com/wp-json/wp/v2/posts?per_page=10&status=publish
The response is a JSON array where each post object contains:
{
"id": 123,
"date": "2026-06-29T10:30:00",
"title": {
"rendered": "WordPress REST API Guide"
},
"content": {
"rendered": "<p>...</p>"
},
"excerpt": {
"rendered": "Learn how to use..."
},
"featured_media": 456,
"categories": [1, 2],
"author": 1,
"status": "publish"
}
You can filter and sort results using query parameters:
?per_page=20— Return 20 posts per page (default is 10)?page=2— Get the second page of results (pagination)?search=api— Search for posts containing "api"?categories=1,2— Return posts from category IDs 1 and 2?orderby=date&order=asc— Sort by date, oldest first?_fields=id,title,date— Return only specific fields to reduce payload size
To fetch a single post by ID:
GET https://example.com/wp-json/wp/v2/posts/123
The single-post response includes more detail than the list view — full content, meta fields, and additional information not exposed in list endpoints.
Authentication with REST API
Write operations (POST, PUT, DELETE) and accessing private/draft posts require authentication to verify the user has permission. WordPress supports several authentication methods:
1. Application Passwords (Recommended)
WordPress 5.6+ provides Application Passwords — special API-only credentials that users generate from WordPress Admin > Users > Your Profile > Application Passwords. These are safer than sharing your real password and can be revoked individually without affecting your main login.
Usage example with cURL:
curl -X POST https://example.com/wp-json/wp/v2/posts \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'username:app-password' | base64)" \
-d '{
"title": "My New Post",
"content": "Post content here",
"status": "publish"
}'
2. OAuth 2.0 (For Third-Party Apps)
WordPress installations with OAuth2 plugins (like OAuth2 Server) allow third-party apps to request access tokens without exposing user passwords. Work is ongoing to add native OAuth2 support to WordPress core.
3. JWT (JSON Web Tokens)
JWT plugins like Simple JWT Authentication provide token-based auth, which works well for Mobile Apps and Single Page Applications (SPAs). The client authenticates once and receives a token that grants time-limited access.
Create, Update, and Delete Data
Once authenticated, you can create, modify, and remove posts and other content:
Create a New Post:
POST https://example.com/wp-json/wp/v2/posts
Authorization: Basic base64(username:app-password)
Content-Type: application/json
{
"title": "My First REST API Post",
"content": "<p>This post was created via REST API</p>",
"excerpt": "A short excerpt",
"featured_media": 789,
"categories": [1, 2],
"tags": [5, 6],
"status": "draft"
}
Supported fields in POST requests:
title— Post titlecontent— Body content (accepts HTML)excerpt— Summary displayed in post listsfeatured_media— ID of the featured image attachmentcategories, tags— Array of category/tag IDsstatus— "draft", "publish", "pending", or "private"comment_status— "open" or "closed"meta— Custom meta fields (if properly registered)
Update an Existing Post:
PUT https://example.com/wp-json/wp/v2/posts/123
Authorization: Basic base64(username:app-password)
Content-Type: application/json
{
"title": "Updated Title",
"content": "<p>Updated content</p>",
"status": "publish"
}
When updating, you only need to include fields you're changing — omitted fields are left unchanged.
Delete a Post:
DELETE https://example.com/wp-json/wp/v2/posts/123?force=true
Authorization: Basic base64(username:app-password)
The force=true parameter permanently deletes the post. Without it, the post moves to trash.
Building Custom Endpoints
Beyond built-in endpoints, WordPress allows developers to create custom endpoints for application-specific functionality:
PHP example showing how to register a custom endpoint:
add_action( 'rest_api_init', function() {
register_rest_route( 'myapp/v1', '/greet', array(
'methods' => 'GET',
'callback' => 'my_greet_callback',
'permission_callback' => '__return_true'
) );
} );
function my_greet_callback( $request ) {
$name = $request->get_param( 'name' );
return new WP_REST_Response( array(
'greeting' => 'Hello, ' . $name . '!'
), 200 );
}
Now you can call:
GET https://example.com/wp-json/myapp/v1/greet?name=John
Custom endpoints are useful for:
- Aggregating complex data from multiple custom post types
- Accepting form submissions from your frontend
- Integrating with payment gateways or third-party services
- Implementing advanced search or filtering logic
Headless WordPress Architecture
A Headless CMS means WordPress handles content management (via Admin Dashboard) but has no theme or frontend — that's built separately using modern frameworks like React, Vue, Next.js, or static site generators. The frontend communicates with WordPress exclusively through REST API.
Benefits of Headless WordPress:
- Flexibility — Build any frontend design you want without theme constraints
- Multi-Channel Publishing — Same content serves web, mobile app, and other platforms simultaneously
- Performance — Next.js and static generators can outpace traditional WordPress themes significantly
- Separation of Concerns — Content teams and frontend developers work independently
Headless WordPress architecture diagram:
┌─────────────────────────────┐
│ WordPress Admin Dashboard │
│ (Content Management) │
├─────────────────────────────┤
│ WordPress Database │
│ REST API Endpoints │
└──────────────────┬──────────┘
│
┌──────────┼──────────┬──────────┐
│ │ │ │
┌──▼──┐ ┌──▼──┐ ┌──▼──┐ ┌──▼──┐
│React│ │Next │ │Mobile│ │IOS │
│Web │ │.js │ │App │ │App │
└─────┘ └─────┘ └──────┘ └─────┘
Example: React component fetching from WordPress REST API:
// React component
import { useEffect, useState } from 'react';
export default function PostList() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('https://example.com/wp-json/wp/v2/posts')
.then(res => res.json())
.then(data => setPosts(data));
}, []);
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title.rendered}</h2>
<p>{post.excerpt.rendered}</p>
</article>
))}
</div>
);
}
REST API Security
The REST API is open to the public by default (for read-only access), so security considerations are important:
1. Disable Unnecessary Endpoints
If your WordPress isn't serving REST requests for user or comment data, consider disabling those endpoints:
// Hide user endpoints from unauthenticated requests
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( ! is_user_logged_in() ) {
unset( $endpoints['/wp/v2/users'] );
unset( $endpoints['/wp/v2/users/(?P<id>[\\d]+)'] );
}
return $endpoints;
} );
2. Use Application Passwords, Not Real Passwords
Always use Application Passwords for API access. You can revoke them instantly without changing your login password, limiting damage if compromised.
3. Implement Rate Limiting
Rate limiting prevents brute-force attacks and DDoS abuse:
// Limit to 100 requests per minute per IP
add_filter( 'rest_throttle_check', function() {
$ip = $_SERVER['REMOTE_ADDR'];
$key = 'rest_limit_' . $ip;
$count = get_transient( $key );
if ( $count >= 100 ) {
return new WP_Error( 'rest_throttled', 'Too many requests' );
}
set_transient( $key, $count + 1, 60 );
} );
4. Always Use HTTPS
Ensure your WordPress hosting uses HTTPS (SSL/TLS) certificates. Application Passwords sent over unencrypted HTTP are vulnerable to interception.
5. Check User Permissions
Verify users have appropriate capabilities before allowing write operations:
register_rest_route( 'myapp/v1', '/admin-only', array(
'callback' => 'my_admin_callback',
'permission_callback' => function() {
return current_user_can( 'manage_options' );
}
) );
Real-World Use Cases
1. Mobile Apps for Your Blog
Native iOS and Android apps can fetch posts from WordPress REST API and display them in app-native formats. Push notifications alert users when new posts are published — creating engagement outside the web browser.
2. Next.js Blog with Static Generation
Next.js getStaticProps fetches posts during build time, generating static HTML. Incremental Static Regeneration (ISR) lets you refresh pages on-demand when content updates. The result is lightning-fast page loads while maintaining dynamic content management through WordPress Admin.
3. Form Submission Logging
Contact forms on React frontends can POST submissions to a WordPress custom post type via REST API. Site admins review submissions directly in the WordPress Admin Dashboard, centralizing all user interactions.
// React form submission
async function handleSubmit(e) {
e.preventDefault();
const response = await fetch(
'https://example.com/wp-json/myapp/v1/submissions',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
body: JSON.stringify({
name: form.name,
email: form.email,
message: form.message
})
}
);
const result = await response.json();
alert('Thank you for your message!');
}
4. Multi-Site Publishing with Jamstack
Organizations with multiple websites can use a single WordPress instance as the content hub. Individual sites built with Hugo, Gatsby, 11ty, or Next.js fetch data via REST API, enabling centralized content management across many properties while maintaining independent frontend architectures.
Frequently Asked Questions
register_meta() with 'show_in_rest' => true. For Advanced Custom Fields (ACF), enable "Show in REST API" in field group settings.