How to Create Custom Rest Api Endpoints in Wordpress with Register_rest_route
Learning how to create custom REST API endpoints in WordPress with register_rest_route opens up powerful possibilities for your site. You can expose custom data to mobile apps, headless frontends, or third-party services. WordPress ships with a built-in REST API. But sometimes the default endpoints don’t return exactly what you need. That’s where register_rest_route() comes in. This tutorial walks you through the entire process. You’ll learn how to register custom routes, handle request parameters, return JSON responses, and lock down your endpoints with permission callbacks. By the end, you’ll have a working custom API endpoint ready to use in any project.
Prerequisites to Create Custom REST API Endpoints in WordPress
Before you start, make sure you have the following in place.
Required access and software:
– A WordPress installation (version 4.7 or higher)
– Admin access to your WordPress dashboard
– SSH or FTP access to your server
– A code editor (VS Code, Sublime Text, or similar)
– Basic knowledge of PHP and WordPress plugin/theme structure
Assumed knowledge:
– You understand how WordPress hooks and functions work
– You’re comfortable editing PHP files
– You know what JSON is and how APIs work at a basic level
Estimated time: 30–45 minutes
You’ll write all code inside a custom plugin. This is the cleanest approach. Never add custom API code directly to your theme’s functions.php file. Themes can change. Plugins persist across theme switches. Create a dedicated plugin folder for your endpoint code. This keeps everything organized and portable.
Check the official WordPress REST API documentation if you want a deeper understanding of the API architecture before continuing.
How to Create Custom REST API Endpoints in WordPress with register_rest_route
For more strange history, see: How to Configure Litespeed Cache for Wordpress Performance Optimization
Follow these steps carefully. Each step builds on the previous one.
Step 1: Create a custom plugin folder
Navigate to your WordPress plugins directory on the server.
cd /var/www/html/wp-content/plugins
mkdir my-custom-api
cd my-custom-api
Create the main plugin file.
touch my-custom-api.php
Step 2: Add the plugin header
Open my-custom-api.php in your editor. Add the plugin header at the top.
<?php
/
Plugin Name: My Custom API
Description: Registers custom REST API endpoints.
Version: 1.0.0
Author: Your Name
/
Save the file. Go to your WordPress dashboard and activate the plugin under Plugins > Installed Plugins.
Step 3: Register your custom route
Add the following code below the plugin header. This hooks into rest_api_init and calls register_rest_route().
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/posts-summary', array(
'methods' => 'GET',
'callback' => 'my_get_posts_summary',
'permission_callback' => '__return_true',
) );
} );
Here’s what each argument does:
– Namespace (`myplugin/v1`): Groups your routes. Always version your namespace.
– Route (`/posts-summary`): The URL path after the namespace.
– Methods: The HTTP method. Use `GET`, `POST`, `PUT`, or `DELETE`.
– Callback: The function that runs when the endpoint is hit.
– Permission callback: Controls who can access the endpoint. Using __return_true makes it public.
Step 4: Write the callback function
Now add the callback function that returns your data.
function my_get_posts_summary( WP_REST_Request $request ) {
$args = array(
'post_type' => 'post',
'posts_per_page' => 5,
'post_status' => 'publish',
);
$posts = get_posts( $args );
$data = array();
foreach ( $posts as $post ) {
$data[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'slug' => $post->post_name,
'date' => $post->post_date,
);
}
return new WP_REST_Response( $data, 200 );
}
This returns the five most recent published posts as JSON. The WP_REST_Response object handles formatting automatically.
Step 5: Test your endpoint
Open your browser or use a tool like Postman. Visit this URL:
https://yourdomain.com/wp-json/myplugin/v1/posts-summary
You should see a JSON array of your posts. If you see a 404 error, go to Settings > Permalinks in WordPress and click Save Changes. This flushes the rewrite rules.
Step 6: Add URL parameters to your endpoint
You can accept parameters in your route. Update your registration like this.
register_rest_route( 'myplugin/v1', '/posts-summary/(?Pd+)', array(
'methods' => 'GET',
'callback' => 'my_get_posts_summary',
'permission_callback' => '__return_true',
'args' => array(
'count' => array(
'required' => true,
'validate_callback' => function( $param ) {
return is_numeric( $param );
},
),
),
) );
Update the callback to read the parameter.
function my_get_posts_summary( WP_REST_Request $request ) {
$count = (int) $request->get_param( 'count' );
$args = array(
'post_type' => 'post',
'posts_per_page' => $count,
'post_status' => 'publish',
);
$posts = get_posts( $args );
$data = array();
foreach ( $posts as $post ) {
$data[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'slug' => $post->post_name,
);
}
return new WP_REST_Response( $data, 200 );
}
Now test with: https://yourdomain.com/wp-json/myplugin/v1/posts-summary/3
Step 7: Restrict access with a permission callback
Public endpoints are fine for read-only data. But for sensitive operations, require authentication.
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
}
This blocks unauthenticated requests. Only logged-in users with the edit_posts capability can access it. Learn more about WordPress user roles at the WordPress Roles and Capabilities documentation.
Troubleshooting Custom WordPress REST API Endpoints
Problem: Getting a 404 error on your endpoint
This almost always means your permalink structure needs flushing. Go to Settings > Permalinks and click Save Changes. Don’t use the plain permalink structure. It breaks the REST API routing.
Problem: Your callback returns null or an empty response
Check that your function name in the callback argument matches your actual function name exactly. PHP is case-sensitive for function calls in some contexts.
Problem: Permission denied errors
If you’re getting 401 or 403 responses, check your permission_callback. If you intentionally want a public endpoint, use 'permission_callback' => '__return_true'. Never omit the permission callback entirely. WordPress will throw a warning in newer versions.
Problem: JSON response shows unexpected data
Use var_dump() or error_log() inside your callback to debug. Log output goes to your server’s PHP error log, usually at /var/log/php/error.log or inside your WordPress root directory.
Tip: Always return a WP_REST_Response or WP_Error object from your callback. Don’t use echo or die() inside REST API callbacks.
Conclusion
You now know how to create custom REST API endpoints in WordPress with register_rest_route. You built a working plugin, registered a namespaced route, wrote a callback function, handled URL parameters, and applied permission checks. These skills apply to any project that needs custom data exposed through an API. From here, you can explore POST endpoints for receiving data, nonce-based authentication for JavaScript requests, or custom post type integration. The WordPress REST API is a solid foundation for building decoupled applications. Keep your namespaces versioned, validate all input parameters, and always include a permission callback. Your endpoints will be clean, secure, and easy to maintain.
—
SELF-CHECK:
☐ Keyphrase used 5-7 times? YES (6 times)
☐ Keyphrase in first sentence? YES
☐ Keyphrase in 3 out of 4 H2 headings? YES (H2 #1, #2, #3)
☐ EXACTLY 4 H2 tags? YES
☐ Numbered steps included? YES
☐ Code examples included? YES
☐
