WordPress rest_prepare_post Example: Extend Headless Post Responses Safely
Extend WordPress post API responses with rest_prepare_post while keeping headless payload shaping deliberate and stable.
Published
May 4, 2026
Reading Time
2 min read
Updated
May 4, 2026

Implementation Notes
Extension points, code paths, and implementation choices that should survive contact with production.
Best For
WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.
Primary Topics
Editorial Focus
Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on May 4, 2026.
Full Report
Last reviewed: May 4, 2026
Headless teams often outgrow the default post payload but still do not need a full custom endpoint. The rest_prepare_post filter is a clean middle layer for extending the standard WordPress post response with computed fields, normalized values, or headless-specific presentation data.
This guide shows how to add a small derived field to the REST post payload safely and how to avoid turning the filter into an unstable dumping ground.
Add a derived field to the prepared post response
<?php
add_filter( 'rest_prepare_post', 'vulnwp_add_reading_time_to_rest_posts', 10, 3 );
function vulnwp_add_reading_time_to_rest_posts( $response, $post, $request ) {
if ( 'view' !== $request->get_param( 'context' ) ) {
return $response;
}
$data = $response->get_data();
$word_count = str_word_count( wp_strip_all_tags( $post->post_content ) );
$data['reading_time_minutes'] = max( 1, (int) ceil( $word_count / 220 ) );
$response->set_data( $data );
return $response;
}
This approach keeps the default route and schema shape intact while adding a new field that a Next.js or another headless frontend can use immediately.
Only add response data that is stable and intentional
Every extra field becomes part of a contract with the frontend. If the field is volatile, request-specific in a surprising way, or redundant with existing core fields, it does not belong in the prepared response.
Respect request context and execution cost
REST filters can run often. Small calculations are fine. Expensive queries inside every post response are not. If a field needs extra database work, cache the result or reconsider whether it belongs on the standard posts endpoint.
Prefer explicit data shaping over hidden markup assumptions
Headless frontends are easier to maintain when WordPress returns concrete values such as reading time, normalized labels, or vetted meta. They are harder to maintain when the frontend has to guess those values by scraping strings out of HTML.
Common mistakes
- Mutating the payload without documenting it. The frontend should know the field exists on purpose.
- Running expensive logic for every response. REST shaping should stay cheap.
- Using the filter to expose sensitive internal data. Public API fields should be reviewed like any other output.
- Ignoring request context. Admin edit flows and public view flows do not always need the same payload shape.
Production checklist
- Add only stable, documented fields to the post response.
- Gate logic by request context when appropriate.
- Keep response shaping lightweight or cache derived values.
- Review the field from the frontend’s point of view before shipping.
- Test the response with real API consumers, not only the browser preview.
Related reading
Pair this with the register_post_meta guide when the data should be a formal meta field, and with the REST pagination article when the frontend is consuming these payloads at archive scale.


