TopSyde
Start Free Trial

WordPress REST API: A Developer's Complete Guide

Master WordPress REST API with authentication, custom endpoints, headless WordPress, and React/Next.js integration. Complete tutorial with real examples.

Marcus Webb

Marcus Webb

DevOps & Security Lead

··8 min read

Last updated: May 16, 2026

WordPress REST API tutorial showing JSON data flow between frontend and backend

WordPress REST API provides a standardized way to interact with your WordPress site programmatically, enabling headless architectures, mobile apps, and third-party integrations through HTTP requests that return JSON responses.

What is the WordPress REST API?

The WordPress REST API is an interface that allows external applications to interact with WordPress sites using standard HTTP methods (GET, POST, PUT, DELETE). It transforms WordPress from a traditional CMS into a flexible content backend that can power websites, mobile apps, and headless architectures.

According to the 2024 WordPress Developer Survey, 34% of developers now use WordPress as a headless CMS, up from 22% in 2022. This growth reflects the API's maturity and the increasing demand for decoupled architectures.

The REST API follows REST (Representational State Transfer) principles, making it intuitive for developers familiar with modern web development. Every WordPress installation since version 4.7 includes the REST API by default, accessible at /wp-json/wp/v2/ endpoints.

How WordPress REST API Authentication Works

WordPress REST API supports multiple authentication methods depending on your security requirements and use case. Understanding these methods is crucial for secure implementation.

Application Passwords

Application Passwords provide the simplest authentication method for trusted applications. Users generate unique passwords specifically for API access, separate from their regular login credentials.

const response = await fetch('https://yoursite.com/wp-json/wp/v2/posts', {
  method: 'POST',
  headers: {
    'Authorization': 'Basic ' + btoa('username:application_password'),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    title: 'New Post via API',
    content: 'Post content here',
    status: 'publish'
  })
});

JWT Token Authentication

JSON Web Tokens provide stateless authentication ideal for modern applications. JWT tokens contain encoded user information and expire after a set time, enhancing security.

OAuth 2.0 Integration

OAuth enables secure third-party application authorization without exposing user credentials. This method works best for applications that need user consent for data access.

WordPress REST API Endpoints Reference

WordPress provides numerous built-in endpoints for common operations. Understanding the endpoint structure helps you navigate the API efficiently.

EndpointHTTP MethodPurposeAuthentication Required
/wp/v2/postsGETRetrieve postsNo
/wp/v2/postsPOSTCreate new postYes
/wp/v2/posts/{id}PUTUpdate existing postYes
/wp/v2/posts/{id}DELETEDelete postYes
/wp/v2/pagesGETRetrieve pagesNo
/wp/v2/usersGETList usersNo (limited data)
/wp/v2/mediaPOSTUpload mediaYes
/wp/v2/commentsGET/POSTManage commentsDepends on settings

Query Parameters and Filtering

The REST API supports extensive filtering and querying capabilities:

// Get 10 latest posts from category ID 5
fetch('/wp-json/wp/v2/posts?per_page=10&categories=5&orderby=date&order=desc')

// Search posts by keyword
fetch('/wp-json/wp/v2/posts?search=wordpress api')

// Get posts by specific author
fetch('/wp-json/wp/v2/posts?author=1')

How to Create Custom REST API Endpoints

Custom endpoints extend WordPress functionality beyond default content types. This enables specialized data handling and business logic implementation.

Basic Custom Endpoint Registration

function register_custom_endpoints() {
    register_rest_route('custom/v1', '/products', array(
        'methods' => 'GET',
        'callback' => 'get_custom_products',
        'permission_callback' => '__return_true'
    ));
}
add_action('rest_api_init', 'register_custom_endpoints');

function get_custom_products($request) {
    $products = get_posts(array(
        'post_type' => 'product',
        'numberposts' => $request->get_param('per_page') ?: 10
    ));
    
    $formatted_products = array_map(function($product) {
        return array(
            'id' => $product->ID,
            'title' => $product->post_title,
            'price' => get_post_meta($product->ID, '_price', true),
            'stock' => get_post_meta($product->ID, '_stock', true)
        );
    }, $products);
    
    return rest_ensure_response($formatted_products);
}

Advanced Endpoint with Validation

function register_advanced_endpoint() {
    register_rest_route('custom/v1', '/orders', array(
        'methods' => 'POST',
        'callback' => 'create_order',
        'permission_callback' => function() {
            return current_user_can('edit_posts');
        },
        'args' => array(
            'customer_email' => array(
                'required' => true,
                'validate_callback' => function($param) {
                    return is_email($param);
                }
            ),
            'items' => array(
                'required' => true,
                'validate_callback' => function($param) {
                    return is_array($param) && !empty($param);
                }
            )
        )
    ));
}

Headless WordPress with React and Next.js

Headless WordPress architectures separate content management from presentation, enabling modern frontend frameworks to consume WordPress data via the REST API.

React Integration Example

import React, { useState, useEffect } from 'react';

function WordPressPosts() {
    const [posts, setPosts] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        async function fetchPosts() {
            try {
                const response = await fetch('/wp-json/wp/v2/posts?per_page=6');
                const postsData = await response.json();
                setPosts(postsData);
            } catch (error) {
                console.error('Error fetching posts:', error);
            } finally {
                setLoading(false);
            }
        }

        fetchPosts();
    }, []);

    if (loading) return <div>Loading posts...</div>;

    return (
        <div className="posts-grid">
            {posts.map(post => (
                <article key={post.id} className="post-card">
                    <h2 dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
                    <div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
                    <a href={post.link}>Read More</a>
                </article>
            ))}
        </div>
    );
}

Next.js Static Generation

Next.js enables static site generation with WordPress data, combining the content management benefits of WordPress with the performance of static sites.

// pages/blog/[slug].js
export async function getStaticPaths() {
    const posts = await fetch('https://yoursite.com/wp-json/wp/v2/posts?per_page=100');
    const postsData = await posts.json();
    
    const paths = postsData.map(post => ({
        params: { slug: post.slug }
    }));

    return {
        paths,
        fallback: 'blocking'
    };
}

export async function getStaticProps({ params }) {
    const post = await fetch(`https://yoursite.com/wp-json/wp/v2/posts?slug=${params.slug}`);
    const postData = await post.json();

    return {
        props: {
            post: postData[0]
        },
        revalidate: 3600 // Revalidate every hour
    };
}

According to Jamstack Community Survey 2024, headless WordPress sites show 43% faster Time to First Byte (TTFB) compared to traditional WordPress themes when properly optimized.

WordPress REST API Performance Optimization

REST API performance directly impacts user experience, especially in headless architectures where every data request affects page load times.

Caching Strategies

Object caching significantly improves REST API response times. TopSyde's managed hosting includes Redis object caching optimized for REST API workloads.

function cache_api_response($endpoint, $data) {
    $cache_key = 'api_' . md5($endpoint . serialize($_GET));
    wp_cache_set($cache_key, $data, 'api_responses', 3600);
}

function get_cached_api_response($endpoint) {
    $cache_key = 'api_' . md5($endpoint . serialize($_GET));
    return wp_cache_get($cache_key, 'api_responses');
}

Database Query Optimization

Minimize database queries in custom endpoints by using efficient WordPress query methods:

function optimized_posts_endpoint($request) {
    // Use WP_Query for complex queries instead of multiple get_posts() calls
    $query_args = array(
        'post_type' => 'post',
        'posts_per_page' => $request->get_param('per_page') ?: 10,
        'meta_query' => array(
            array(
                'key' => '_featured',
                'value' => 'yes',
                'compare' => '='
            )
        )
    );
    
    $posts_query = new WP_Query($query_args);
    
    // Use get_field() for ACF fields to avoid individual meta queries
    $formatted_posts = array_map(function($post) {
        return array(
            'id' => $post->ID,
            'title' => $post->post_title,
            'featured_image' => get_field('featured_image', $post->ID),
            'excerpt' => wp_trim_words($post->post_content, 30)
        );
    }, $posts_query->posts);
    
    return rest_ensure_response($formatted_posts);
}

Response Field Selection

Limit API responses to necessary fields to reduce payload size and transfer time:

// Request only specific fields
fetch('/wp-json/wp/v2/posts?_fields=id,title,excerpt,date,link')

// Embed related data in single request
fetch('/wp-json/wp/v2/posts?_embed=author,wp:featuredmedia')

WordPress REST API Security Best Practices

REST API security requires multiple layers of protection, from authentication to input validation and rate limiting.

Rate Limiting Implementation

Prevent API abuse with rate limiting based on IP address or user authentication:

function implement_api_rate_limiting() {
    $ip = $_SERVER['REMOTE_ADDR'];
    $rate_limit_key = 'api_rate_limit_' . md5($ip);
    
    $current_requests = get_transient($rate_limit_key) ?: 0;
    
    if ($current_requests >= 100) { // 100 requests per hour
        wp_die('Rate limit exceeded', 'Too Many Requests', array('response' => 429));
    }
    
    set_transient($rate_limit_key, $current_requests + 1, 3600);
}
add_action('rest_api_init', 'implement_api_rate_limiting');

Input Validation and Sanitization

Validate all input data to prevent injection attacks and data corruption:

function validate_custom_endpoint_data($request) {
    $email = sanitize_email($request->get_param('email'));
    if (!is_email($email)) {
        return new WP_Error('invalid_email', 'Invalid email format', array('status' => 400));
    }
    
    $content = wp_kses_post($request->get_param('content'));
    if (empty($content)) {
        return new WP_Error('empty_content', 'Content cannot be empty', array('status' => 400));
    }
    
    return true;
}

HTTPS and CORS Configuration

Always use HTTPS for API endpoints handling sensitive data. Configure CORS headers for cross-origin requests:

function configure_api_cors() {
    header('Access-Control-Allow-Origin: https://yourdomain.com');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Authorization, Content-Type');
}
add_action('rest_api_init', 'configure_api_cors');

For comprehensive WordPress security practices, review our WordPress Security Best Practices guide.

Real-World WordPress REST API Use Cases

E-commerce Integration

WooCommerce REST API extends WordPress capabilities for online stores:

// Retrieve products with pricing and inventory
async function getProducts(category = null) {
    let url = '/wp-json/wc/v3/products';
    if (category) {
        url += `?category=${category}`;
    }
    
    const response = await fetch(url, {
        headers: {
            'Authorization': 'Basic ' + btoa('consumer_key:consumer_secret')
        }
    });
    
    return await response.json();
}

// Create new order
async function createOrder(orderData) {
    const response = await fetch('/wp-json/wc/v3/orders', {
        method: 'POST',
        headers: {
            'Authorization': 'Basic ' + btoa('consumer_key:consumer_secret'),
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(orderData)
    });
    
    return await response.json();
}

Mobile App Backend

WordPress REST API serves as a robust backend for mobile applications:

// Mobile app authentication flow
class WordPressAuth {
    async login(username, password) {
        const response = await fetch('/wp-json/jwt-auth/v1/token', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ username, password })
        });
        
        const data = await response.json();
        if (data.token) {
            await AsyncStorage.setItem('jwt_token', data.token);
            return true;
        }
        return false;
    }
    
    async getProfile() {
        const token = await AsyncStorage.getItem('jwt_token');
        const response = await fetch('/wp-json/wp/v2/users/me', {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        
        return await response.json();
    }
}

Multi-site Content Syndication

REST API enables content sharing across multiple WordPress installations:

function sync_content_across_sites($post_id) {
    $post = get_post($post_id);
    $sites = ['https://site1.com', 'https://site2.com'];
    
    foreach ($sites as $site) {
        $response = wp_remote_post($site . '/wp-json/wp/v2/posts', array(
            'headers' => array(
                'Authorization' => 'Basic ' . base64_encode('username:password'),
                'Content-Type' => 'application/json
Marcus Webb
Marcus Webb

DevOps & Security Lead

12+ years DevOps, Linux & cloud infrastructure certified

Marcus leads infrastructure and security at TopSyde, managing the server fleet and AI monitoring systems that keep client sites fast and protected. Former sysadmin turned WordPress hosting specialist.

Related Articles

View all →

Stop managing your WordPress site

Let our team handle hosting, speed, security, and updates — so you can focus on what matters.

Get Started Free