Create REST API in WordPress (With Examples)

WordPress empowers millions of websites globally and it becomes a powerful headless CMS when the WordPress REST API is utilized. Learn in this post, how to create a WordPress API with example code.

REST API in WordPress

A WordPress REST API is a set of endpoints that allows developers to interact with website data through HTTP requests. It is a structured and JSON based interface to retrieve, create, update and delete website data in a flexible way. In this post, we will learn how to access WordPress API endpoints and how to create custom endpoints with examples.

 

How to Access WordPress API Endpoints

The REST API in WordPress is enabled by default since version 4.7 and later. The endpoints of the REST API can be accessed by appending /wp-json/ to the website URL to fetch website details, while for other endpoints like posts, pages and users, it can be accessed by appending /wp-json/wp/v2/ to the URL. The following are WordPress API endpoints available by default:

  • /posts: To get, create, update and delete posts.
  • /pages: To get, create, update and delete pages.
  • /categories: To get, create, update and delete categories.
  • /tags: To get, create, update and delete tags.
  • /comments: To get, create, update and delete comments.
  • /users: To get, create, update and delete users.

For the sake of example, we will be using the posts endpoints. So to get posts, we will use the endpoint with a GET request like this:

GET https://example.com/wp-json/wp/v2/posts

To create a post, we will need to send a POST request to the posts endpoint with authentication headers like this:

POST https://example.com/wp-json/wp/v2/posts

// Headers
Authorization: Basic base64encoded(username:password)
Content-Type: application/json

// Body
{
"title": "My New Post",
"content": "This is the content of the new post.",
"status": "publish"
}

To update a post, we will send a POST request to the posts endpoint with authentication headers like in the create post example:

POST https://example.com/wp-json/wp/v2/posts/1

// Headers
Authorization: Basic base64encoded(username:password)
Content-Type: application/json

// Body
{
"title": "Update post title",
}

To delete a post, we will send a DELETE request to the posts endpoint with authentication headers. The query parameter ?force=true can be used to force post to delete instead of moving to trash like this: 

DELETE https://example.com/wp-json/wp/v2/posts/1

// Headers
Authorization: Basic base64encoded(username:password)

These were the four basic examples of how to use built-in REST API endpoints in WordPress.

 

How to Register Custom REST API Endpoints in WordPress

In addition to default REST endpoints available in WordPress, it allows developers to create their own custom REST API endpoints, making it flexible for developers to manage website data efficiently via headless API requests. The following are the steps to register a custom REST API endpoint in WordPress with some PHP code:

  • Add an action for rest_api_init, providing the function to register API endpoints.
  • Inside the function, use the WordPress function register_rest_route() with three parameters. The first one is the endpoint prefix, the second one is the specific API endpoint and the third one is an array of arguments.
  • Add the request methods allowed for this specific endpoint.
  • Add the callback function to process the API request and return a response.
  • Add the permission check callback function if the endpoint requires a permission check.
// Action hook to register custom REST API endpoints
add_action('rest_api_init', 'custom_rest_routes');
function custom_rest_routes(): void
{
register_rest_route('custom-endpoint/v1', '/custom-posts/', [
'methods' => WP_REST_Server::ALLMETHODS,
'callback' => 'custom_posts_rest_callback',
'permission_callback' => 'custom_posts_rest_permissions_callback',
]);
}

// Callback function to process API request and return response
function custom_posts_rest_callback(WP_REST_Request $request)
{
// The code logic goes here
}

// Check the permissions here
function custom_posts_rest_permissions_callback()
{
return current_user_can('manage_options');
}

This is a general example of registering any API endpoint in WordPress. We hook into the rest_api_init hook and register REST routes using the register_rest_route() function with a callback function to process the request and return the response and a permission callback function. The above code snippet can register a specific REST route for all HTTP methods. We can handle different HTTP methods differently. All these methods should then return a WP JSON response.

 

GET API Request in WordPress (GET Method)

The GET method is used to fetch data or a set of data from the server. It only retrieves data not modifies it, like retrieving all posts or retrieving a single post, providing the post ID as a parameter. The WP REST route for the GET method can be registered like this:

// Get all posts or single post API endpoint
register_rest_route('custom-endpoint/v1', '/custom-posts/', [
[
'methods' => WP_REST_Server::READABLE, // GET
'callback' => 'get_custom_posts',
'permission_callback' => 'custom_posts_rest_permissions_callback',
]
]);

// Callback function to process request and return response
function get_custom_posts(WP_REST_Request $request): WP_REST_Response
{
$posts = get_posts([
'post_type' => 'post',
'posts_per_page' => 5,
'post_status' => 'publish',
]);

$data = [];

foreach ($posts as $post) {
$data[] = [
'id' => $post->ID,
'title' => get_the_title($post->ID),
'content' => apply_filters('the_content', $post->post_content),
'date' => $post->post_date,
];
}

return new WP_REST_Response($data, 200);
}

// Get specific post by ID API endpoint
register_rest_route('custom-endpoint/v1', '/custom-posts/(?P<id>\d+)', [
[
'methods' => WP_REST_Server::READABLE, // GET
'callback' => 'get_custom_post',
'permission_callback' => 'custom_posts_rest_permissions_callback',
]
]);

// Callback function to process request and return response
function get_custom_post(WP_REST_Request $request): WP_REST_Response
{
$post_id = (int) $request['id'];

$post = get_post($post_id);

if (!$post) {
return new WP_REST_Response([
'message' => __('Failed to get post', 'text-domain')
], 400);
}

return new WP_REST_Response($post, 200);
}
 

Create API Request in WordPress (POST Method)

The POST method is used to create a new resource on the server, where the data is sent in the request body. The WP REST route for the POST method to create a resource can be registered like this:

// Create a post API endpoint
register_rest_route('custom-endpoint/v1', '/custom-posts/', [
[
'methods' => WP_REST_Server::CREATABLE, // POST
'callback' => 'custom_create_post',
'permission_callback' => 'custom_posts_rest_permissions_callback',
],
]);

// Callback function to create a post and return response
function create_custom_post(WP_REST_Request $request): WP_REST_Response
{
$title = sanitize_text_field($request->get_param('title'));
$content = wp_kses_post($request->get_param('content'));

$post_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish',
'post_type' => 'post',
]);

if (is_wp_error($post_id)) {
return new WP_REST_Response([
'message' => __('Failed to create post', 'text-domain')
], 400);
}

return new WP_REST_Response([
'message' => __('Post created successfully', 'text-domain'),
'post_id' => $post_id
], 201);
}
 

Update API Request in WordPress (POST Method)

The update request uses the same POST method, with one difference that it accepts the ID of the resource to update. This does not create a new resource and WP REST route for POST method to update a resource can be registered like this:

// Update a post API endpoint
register_rest_route('custom-endpoint/v1', '/custom-posts/(?P<id>\d+)', [
[
'methods' => WP_REST_Server::EDITABLE, // POST (Update)
'callback' => 'update_custom_post',
'permission_callback' => 'custom_posts_rest_permissions_callback',
]
]);

// Callback function to update a post and return response
function update_custom_post(WP_REST_Request $request): WP_REST_Response
{
$post_id = (int) $request['id'];

$title = sanitize_text_field($request->get_param('title'));
$content = wp_kses_post($request->get_param('content'));

$updated = wp_update_post([
'ID' => $post_id,
'post_title' => $title,
'post_content' => $content,
], true);

if (is_wp_error($updated)) {
return new WP_REST_Response([
'message' => __('Failed to update post', 'text-domain')
], 400);
}

return new WP_REST_Response([
'message' => __('Post updated successfully', 'text-domain'),
'post_id' => $post_id
], 200);
}
 

Delete API Request in WordPress (DELETE Method)

The DELETE method is used to delete a resource on the server, where it expects an ID of the resource to uniquely identify it and delete it. The WP REST route for the DELETE method can be registered like this:

// Delete a post by id API endpoint
register_rest_route('custom-endpoint/v1', '/custom-posts/(?P<id>\d+)', [
[
'methods' => WP_REST_Server::DELETABLE, // DELETE
'callback' => 'delete_custom_post',
'permission_callback' => 'custom_posts_rest_permissions_callback',
],
]);

// Callback function to delete a post and return response
function delete_custom_post(WP_REST_Request $request): WP_REST_Response
{
$post_id = (int) $request['id'];

$deleted = wp_delete_post($post_id, true); // true = force delete

if (!$deleted) {
return new WP_REST_Response([
'message' => __('Failed to delete post', 'text-domain')
], 400);
}

return new WP_REST_Response([
'message' => __('Post deleted successfully', 'text-domain'),
'post_id' => $post_id
], 200);
}

We just demonstrated how to create a custom REST API in WordPress, which can be accessed at https://example.com/wp-json/custom-endpoint/v1/custom-posts with methods to get, add, update and delete posts via API. This feature of WordPress REST API makes it a powerful tool and transforms it from just a CMS to a flexible platform through API endpoints. Always remember to add authentication to secure API calls when data is supposed to change and always sanitize user input for security.