Crafting Custom API Endpoints in WordPress


A few months ago, I embarked on a project to build a mobile application based on an existing WordPress website while preserving existing user data. At the time, I had no knowledge of how WordPress worked, but it has been a rewarding journey of research and learning. In this article, I’ll share how you can create a similar application.
WordPress’s flexibility as a CMS makes it a powerful platform for building custom API endpoints. Creating effective endpoints requires understanding WordPress’s database structure and data storage. In this post, I’ll explore its database architecture, explain how WordPress stores data, and guide you through building a custom API endpoint to retrieve it. Let’s dive in!
WordPress Architecture for APIs
To build custom endpoints, you need to understand WordPress’s core components:
Core Structure: PHP-based, with wp-content (themes/plugins) and wp-includes (core functions) driving extensibility.
Database: MySQL tables (wp_posts, wp_postmeta, etc.) store content, queried for API responses.
REST API: Built into WordPress since 4.7, using JSON routes (e.g., /wp-json/wp/v2/posts) to expose data.
Plugins: The go-to method for adding custom endpoints, keeping code modular.
This architecture enables seamless integration with external apps via custom APIs.
WordPress Database Structure
WordPress uses MySQL to store content in a relational database. The default table prefix is wp_, though it can be customized (e.g., custom_). Key tables for API development include:
wp_posts: Stores core content like posts, pages, and custom post types. Key columns:
ID: Unique post identifier.
post_type: Defines content type (e.g., post, page, event).
post_status: Status like publish, draft, or pending.
post_title, post_content: Content details.
wp_postmeta: Stores metadata for posts in key-value pairs. Columns:
meta_id: Unique identifier.
post_id: Links to wp_posts.ID.
meta_key: Name of the metadata (e.g., _event_date).
meta_value: The stored value.
wp_users: Stores user data like user_login, user_email, and ID.
wp_usermeta: Stores user metadata, similar to wp_postmeta.
wp_options: Stores site-wide settings (e.g., siteurl, blogname).
How Data is Stored
Posts and Custom Post Types: A blog post or custom type like an “event” is a row in wp_posts. Additional data (e.g., event date, location) is stored in wp_postmeta with the post_id linking back to the post.
Users: User profiles are in wp_users, with extra details (e.g., phone number) in wp_usermeta.
Flexibility: The meta tables allow WordPress to handle diverse data without schema changes, making it ideal for custom APIs. I fell in love with this aspect.
This structure enables querying specific data for API responses, such as retrieving posts with their metadata.
Building a Custom API Endpoint
Let’s create an endpoint to fetch all posts of a custom post type (event) with their metadata. We’ll use a plugin for modularity and tap into the WordPress REST API.
Step 1: Set Up the Plugin
Create a plugin file (e.g., wp-content/plugins/custom-api/custom-api.php
):
<?php
/*
Plugin Name: Custom API
Description: Adds custom API endpoints for WordPress.
*/
You can also install a plugin called code snippets
. This gives you a well structured environment to write modular codes. In my case, a snippet was created for authentication
, another for user
related activities, and many others, as I continued to work on the application.
Step 2: Register the Endpoint
Use rest_api_init
to register a route that retrieves events and their metadata:
add_action('rest_api_init', function () {
register_rest_route('customapi/v1', '/events', [
'methods' => 'GET',
'callback' => 'get_custom_events',
'permission_callback' => function () {
return current_user_can('read'); // Restrict to logged-in users
},
]);
});
Step 3: Fetch Data from the Database
Write the callback to query wp_posts
and wp_postmeta
using WP_Query
:
function get_custom_events(WP_REST_Request $request) {
$args = [
'post_type' => 'event',
'post_status' => 'publish',
'posts_per_page' => 10, // Limit to 10 events
];
$query = new WP_Query($args);
$events = [];
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
$events[] = [
'id' => $post_id,
'title' => get_the_title(),
'content' => get_the_content(),
'meta' => get_post_meta($post_id), // Fetch all metadata
];
}
wp_reset_postdata();
}
return rest_ensure_response($events);
}
This code:
Queries the
wp_posts
table for event posts.Retrieves metadata from
wp_postmeta
usingget_post_meta()
.Returns a JSON array of events with their
ID
,title
,content
, andmetadata
.
Step 4: Secure and Test
Security: The
permission_callback
ensures only authorized users access the endpoint. For public access, replace with__return_true
, but add rate limiting or caching.Testing: Use Postman to hit
https://yoursite.com/wp-json/customapi/v1/events
. Expect a response like:[ { "id": 123, "title": "Tech Conference", "content": "Join us for a day of innovation!", "meta": { "_event_date": ["2025-05-01"], "_location": ["Online"] } } ]
Why It Matters
Custom endpoints let you:
Expose tailored data (e.g., events with metadata) for apps or headless setups.
Query the database efficiently using WordPress’s built-in functions.
Build scalable APIs with minimal overhead.
What’s Next?
We’ve laid the foundation for custom API endpoints by leveraging WordPress’s database structure. In my next post, I’ll guide you through building a secure authentication flow for your APIs, exploring methods like JWT and OAuth to protect your endpoints and ensure only authorized users can access sensitive data. Stay tuned for a step-by-step tutorial!
💡 Your Turn: Have you experimented with WordPress APIs? Share your thoughts or questions below! #WordPress #RESTAPI #WebDev
Subscribe to my newsletter
Read articles from Collins01 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Collins01
Collins01
I am a Software Engineer. I focus on building scalable and high performing Websites, Mobile Applications and Backend services.