register_rest_field with a schema, so a client can discover it

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.