REST API

The REST API powers the block editor and every headless WordPress build. This group covers registering custom routes, filtering what a response actually contains, and controlling who's allowed to call it. 2 actions, 3 filters in this category.

rest_prepare_post

rest-api

Filters the REST API response for a single post before it's sent

rest_prepare_post lets you add or remove fields on the /wp/v2/posts response without touching register_rest_field — useful for last-mile shaping of what the API returns.

Signature

apply_filters( 'rest_prepare_post', WP_REST_Response $response, WP_Post $post, WP_REST_Request $request );

Example

add_filter( 'rest_prepare_post', function( $response, $post ) {
    $response->data['reading_time'] = ceil( str_word_count( $post->post_content ) / 200 );
    return $response;
}, 10, 2 );

Common Use Cases

  • Add computed/derived fields to the REST response
  • Strip sensitive fields from public API output
  • Reshape data for a headless front-end
since 4.7.0wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

rest_api_init

rest-api

Fires when the REST API is initialized — register custom routes here

rest_api_init is the register_rest_route() equivalent of init — it only fires on REST requests, not every page load.

Signature

do_action( 'rest_api_init', WP_REST_Server $wp_rest_server );

Example

add_action( 'rest_api_init', function() {
    register_rest_route( 'my-plugin/v1', '/books', [
        'methods'  => 'GET',
        'callback' => 'my_plugin_get_books',
        'permission_callback' => '__return_true',
    ] );
} );

Common Use Cases

  • Register custom REST routes
  • Expose extra fields on existing endpoints via register_rest_field
  • Add custom REST authentication logic
since 4.4.0wp-includes/rest-api.php

rest_pre_dispatch

rest-api

Short-circuits a REST API request before routing

rest_pre_dispatch lets you intercept a REST API request before WordPress even matches it to a route — the earliest point to block or fake a response.

Signature

apply_filters( 'rest_pre_dispatch', mixed $result, WP_REST_Server $server, WP_REST_Request $request );

Example

add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) {
    if ( str_starts_with( $request->get_route(), '/my-plugin/v1' ) && ! is_user_logged_in() ) {
        return new WP_Error( 'forbidden', 'Login required', [ 'status' => 401 ] );
    }
    return $result;
}, 10, 3 );

Common Use Cases

  • Block REST API access globally or per-route before any processing
  • Serve a cached response without running the real route logic
  • Rate-limit or IP-block at the earliest possible point
  • Mock or A/B test an endpoint's response
since 4.4.0wp-includes/rest-api/class-wp-rest-server.php

rest_authentication_errors

rest-api

Filters whether a REST API request should be blocked as unauthenticated

rest_authentication_errors runs after WordPress's own authentication checks (cookie, application passwords) and is the standard hook for adding custom auth schemes or short-circuiting requests with an error.

Signature

apply_filters( 'rest_authentication_errors', WP_Error|null|bool $errors );

Example

add_filter( 'rest_authentication_errors', function( $errors ) {
    error_log( 'REST auth check ran.' );
    return $errors;
} );

Common Use Cases

  • Add a custom authentication scheme (API keys, JWT, signed requests)
  • Restrict the entire REST API to logged-in users only
  • Log authentication attempts for security monitoring
  • Enforce IP allowlisting for headless integrations
since 4.4.0wp-includes/rest-api.php

rest_insert_post

rest-api

Fires after a post is created or updated through the REST API

rest_insert_post is the REST-specific counterpart to save_post — it fires inside the Posts controller with the actual REST request object available, which save_post alone doesn't give you.

Signature

do_action( 'rest_insert_post', WP_Post $post, WP_REST_Request $request, bool $creating );

Example

add_action( 'rest_insert_post', function( $post, $request, $creating ) {
    error_log( ( $creating ? 'Created' : 'Updated' ) . ' post via REST: ' . $post->ID );
}, 10, 3 );

Common Use Cases

  • Read the REST request (headers, client info) at save time
  • Tag content created by a headless front-end or external app
  • Run REST-specific validation after the write
  • Trigger a webhook only for API-originated changes
since 4.7.0wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php