Adding a computed field to a REST response by filtering the prepared object works and leaves the field undocumented, so nothing but your own client knows it exists.
register_rest_field( 'post', 'reading_time', array(
'get_callback' => function ( $post ) {
return turkerdev_get_reading_time( $post['id'] );
},
'schema' => array(
'description' => __( 'Estimated reading time in minutes.', 'turkerdev' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
),
) );
The schema entry is what puts the field in the OPTIONS response, so a client can discover it rather than being told about it in an email. context controls whether it appears in a list response, which matters for anything expensive — a field computed per post across a hundred-item collection is a hundred computations on every request. Removing a field once clients depend on it is a breaking change, so the schema is a contract rather than documentation.