Creating POST Endpoints for Data Submission in WordPress REST API
Master the WordPress REST API by creating POST endpoints. Learn to extract request bodies, sanitize data, and insert new posts into the database securely.
Previously in this course, we explored handling GET requests in REST API to retrieve our Knowledge Base entries. Now that we can fetch data, it's time to allow our React admin interface to push new content to the server.
In this lesson, we will implement the "Create" part of our CRUD operations by building a custom POST endpoint.
Mapping Callbacks to HTTP POST
When you register a route using register_rest_route, you define the allowed HTTP methods in the $args array. While a GET request retrieves data, a POST request is intended for creating new resources.
To handle POST requests, we set the methods key to WP_REST_Server::CREATABLE. This constant maps to the POST verb.
PHPregister_rest_route( 'kb/v1', '/entry', [ 'methods' => WP_REST_Server::CREATABLE, 'callback' => 'kb_handle_create_entry', 'permission_callback' => 'kb_user_can_create', ] );
If you need a refresher on setting up the route structure, see anatomy of a REST API endpoint. Additionally, always ensure you have implemented proper REST API permission callbacks to verify that only authorized users can submit new entries.
Extracting Request Body Data
Unlike GET requests where data usually arrives via URL parameters, POST requests carry data in the request body, typically as JSON. In your callback function, the WP_REST_Request object provides a helper method called get_json_params() or simply get_param() to access this payload.
Before processing, we must validate and sanitize the input. I highly recommend using the schema validation features covered in validating and sanitizing API arguments.
PHPfunction kb_handle_create_entry( WP_REST_Request $request ) { #6A9955">// Extract parameters from the request body $title = sanitize_text_field( $request->get_param( 'title' ) ); $content = sanitize_textarea_field( $request->get_param( 'content' ) ); if ( empty( $title ) ) { return new WP_Error( 'missing_title', 'The title is required.', [ 'status' => 400 ] ); } #6A9955">// Proceed to insertion... }
Inserting Data into the Database
Once the data is cleaned, we use the standard WordPress function wp_insert_post. This function handles the complex logic of creating a row in the wp_posts table and assigning metadata.
Crucially, wp_insert_post returns the ID of the new post on success or a WP_Error object on failure. We must check this return value to provide a proper response to our React frontend.
PHPfunction kb_handle_create_entry( WP_REST_Request $request ) { $title = sanitize_text_field( $request->get_param( 'title' ) ); $content = sanitize_textarea_field( $request->get_param( 'content' ) ); $post_id = wp_insert_post( [ 'post_title' => $title, 'post_content' => $content, 'post_type' => 'knowledge_base', 'post_status' => 'publish', ] ); if ( is_wp_error( $post_id ) ) { return new WP_REST_Response( [ 'message' => 'Failed to create post' ], 500 ); } return new WP_REST_Response( [ 'id' => $post_id, 'message' => 'Entry created' ], 201 ); }
Hands-on Exercise
- Open your plugin's main REST registration file.
- Add a new route for
POST /kb/v1/entry. - Implement the callback to extract
titleandcontent. - Use
wp_insert_postto save the entry as aknowledge_basepost type. - Test your endpoint using Postman or
curl. Send a JSON payload:{"title": "New Entry", "content": "Hello World"}. Verify that a new post appears in your WordPress admin dashboard.
Common Pitfalls
- Missing JSON headers: When sending data from your React client, ensure your fetch request includes
Content-Type: application/json. Without this, WordPress may not parse the request body correctly. - Forgetting to sanitize: Never trust input from the
WP_REST_Requestobject. Always pass data throughsanitize_text_fieldor appropriate HTML filters before it touches the database. - Ignoring return types:
wp_insert_postcan return0or aWP_Error. Always handle these cases to prevent silent failures or fatal errors.
Recap
We have successfully extended our API to handle data submission. By mapping our callback to WP_REST_Server::CREATABLE, extracting sanitized input, and utilizing wp_insert_post, we've built a robust foundation for our Knowledge Base entry creation. This pattern of REST API data insertion is the backbone of any interactive React-powered WordPress plugin.
Up next: We will explore how to handle updates to these resources using ID-based routing and HTTP PUT/PATCH methods.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs โ the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard โ by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.
