ADVERTISEMENT

Wordpress - WP REST API only returning partial list of users

To anyone who might still be hitting this problem, here's a checklist:

  1. Make sure you are authenticated AND your user has the list_users capability.

Example: When adding a custom role, I make sure to add the list_users capability. The user should also be logged in (what authenticated means) when making the request.

  1. By default, only users who have published posts are returned by the request. To disable this, you can remove has_published_posts from the query args, like so:

Add normally

add_filter('rest_user_query', 'remove_has_published_posts_from_api_user_query', 10, 2);
function remove_has_published_posts_from_api_user_query($prepared_args, $request)
{
    unset($prepared_args['has_published_posts']);

    return $prepared_args;
}

or within namespace

add_filter('rest_user_query', __NAMESPACE__ . '\remove_has_published_posts_from_api_user_query', 10, 2);
function remove_has_published_posts_from_api_user_query($prepared_args, $request)
{
    unset($prepared_args['has_published_posts']);

    return $prepared_args;
}

I think it depends on the specifics on what your looking for, you can gain the most control by making your own route tough, the users route is more meant to list out users, not exactly search them as there is a pretty crazy amount of stuff you could be wanting to search based off of, and doing that all through parameters might get difficult.

I am not saying it cannot be done, I just found personally that rather then fighting to get a route to follow your use case, building out custom routes is easier.

Here is an example:

// namespace is like app/v1 rather then wp/v2
register_rest_route($namespace, '/users', array(
    'methods'             => WP_REST_Server::READABLE,
    'callback'            => 'get_user_list',
    'show_in_rest' => true
));

then for the function get_user_list

function get_user_list($request) {
   //below you can change to a WQ_Query and customized it to ensure the list is exactly what you need
   $results = get_users();

   //Using the default controller to ensure the response follows the same structure as the default route
   $users = array();
   $controller = new WP_REST_Users_Controller();
   foreach ( $results as $user ) {
        $data    = $controller->prepare_item_for_response( $user, $request );
        $users[] = $controller->prepare_response_for_collection( $data );
    }

   return rest_ensure_response( $users );
}

Of course there is more too it (like pagination).

https://github.com/WordPress/WordPress/blob/master/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php will show you how it builds the standard route through the get_items function. Depending on what you want to query by it could also tell you the options you need to query by (if using the default route).

The only reason I am giving such a complicated answer as it could help you learn the ins and out of how it works and what application of the REST API might suite your needs.


After much reading I found the reason why all users are not returned with the straight-forward HTTP request for WP REST API:

This is a non-authenticated request, therefore only publicly available users data is released in a GET request.

*** It's important to mention that if some data you need is unavailable, you probably need to add those fields to responses, using register_api_fields (see docs for example usage), to your user endpoints as well.

The best resource I found, which gave me this answer, was part of the detailed and easy-to-read guide on the WP REST API from Torque (see pages 35-38). Someone needs to buy that man many, many beers for writing such a great guide!!