Api rest_route 404 while building filter for custom posts (filtered by multiple meta keys / custom fields)

As I said in my comment, I made a POST request to your custom endpoint (here) and then received a 404 error with this message: “No route was found matching the URL and request method.“, which likely means the route was never registered, or that the request method was not supported, i.e. not in the methods list specified during registration (using register_rest_route()).

So you just need to ensure the route is registered properly and that your (AJAX) request is using the correct HTTP request method, and then the 404 error would be gone.

And in your case, you can ensure the route is registered properly by loading the testimonials_results.php file from within the theme’s functions.php file. E.g.

// Assuming the file is at the same level as the functions.php file
require_once __DIR__ . '/testimonials_results.php';

Other issues in your code

  1. The $metaQueries variable is not defined, and should be defined before the if (isset($_REQUEST['continent']) ...) line.

  2. The isset($_REQUEST['region']) should not be commented out, because otherwise if only the region parameter specified, then your custom posts query would never run.

  3. The above posts query will also run only if $metaQueries has 2 or more items, so if the array is empty or has just 1 item, the $query in your return part would be an undefined and results in a PHP notice saying Undefined variable: query.

    And it’s up to you on how should that be fixed.. but for example, you could add an else, and return an error.

  4. When the WP_Query class is instantiated with a non-empty args, i.e. new WP_Query($args) as opposed to new WP_Query(), the get_posts() method will be automatically called, hence you should not call it manually.

    So replace the $query->get_posts() with $query->posts to access/retrieve the posts that already retrieved via the automatic call to the get_posts() method.

  5. From the REST API handbook:

    Importantly, a REST API route’s callback should always return data;
    it shouldn’t attempt to send the response body itself. This ensures
    that the additional processing that the REST API server does, like
    handling linking/embedding, sending headers, etc… takes place. In
    other words, don’t call die( wp_json_encode( $data ) ); or
    wp_send_json( $data ).

    So don’t call wp_send_json_success() (which uses wp_send_json()), and simply return the data. I.e. return [ 'results' => $result, ... ];

Additional Notes/Info

  1. WordPress has a __return_true() function, so you could simply do 'permission_callback' => '__return_true' 🙂

  2. The $args = array_merge($args, [ 'meta_query' => $metaQueries ]); could just be written as $args['meta_query'] = $metaQueries; ..