How to get posts in backbone where a custom field matches a value?

The REST API endpoint “List Posts” (e.g. GET /wp/v2/posts) does not support filtering the posts by a post meta (or custom field), therefore passing post meta parameters like meta_key and meta_value will by default do nothing.

But the rest_<post type>}_query filter can be used to manually add custom meta queries to the query arguments passed to WP_Query.

Here’s an example for the core post type, but validation and sanitization is up to you…

add_filter( 'rest_post_query', 'my_filter_rest_post_query', 10, 2 );
function my_filter_rest_post_query( $args, $request ) {
    if ( isset( $request['meta_key'] ) ) {
        $args['meta_key'] = $request['meta_key'];

        // If the request did not include the meta_value parameter, or that it's a
        // null, then we do not set the meta_value argument. Which means, the API
        // response would include any posts that have the meta, regardless the value.
        if ( isset( $request['meta_value'] ) ) {
            $args['meta_value'] = $request['meta_value'];
        }
    }

    return $args;
}

So with that, your Backbone code should now work, but a better option, which makes use of the core validation functions, where validation is by default done automatically for you, is by registering your custom request parameter using the rest_<post type>_collection_params filter.

Here’s an example where I used a single custom parameter named meta_status for your status meta:

add_filter( 'rest_post_collection_params', 'my_filter_rest_post_collection_params' );
function my_filter_rest_post_collection_params( $query_params ) {
    $query_params['meta_status'] = array(
        'anyOf' => array(
            array( 'type' => 'string' ),
            array( 'type' => 'null' ), // Allows a real null value.
        ),
        // Your other arguments here.
    );

    return $query_params;
}

Now the filter callback might look like:

add_filter( 'rest_post_query', 'my_filter_rest_post_query', 10, 2 );
function my_filter_rest_post_query( $args, $request ) {
    if ( array_key_exists( 'meta_status', $request->get_params() ) ) {
        $args['meta_key'] = 'status';

        // I've allowed a null value, therefore, if the meta_value parameter is a
        // null, then we do not set the meta_value argument. Which means, the API
        // response would include any posts that have the meta, regardless the value.
        if ( isset( $request['meta_status'] ) ) {
            $args['meta_value'] = $request['meta_status'];
        }
    }

    return $args;
}

tech