WordPress REST API V2 return all posts

I am missing the function to get ALL the posts (or CPT) by using

example.com/wp-json/wp/v2/country/?per_page=-1

or any similiar. The documentation gives as much info as this:

Read More

per_page: Maximum number of items to be returned in result set.

Default: 10

And in another question about the per_page we learn that the allowed range is 1 to 100.

In my case there will be a limited number of posts I need to get, but it will be around 200-300. Are there any workarounds to get them all other than fetching everything page per page and stitching it together?

Additional info if it does matter: I am using angular.js

Related posts

13 comments

  1. Try this instead for pagination. It returns all the posts on my site.

    http://example.com/wp-json/wp/v2/posts/?filter[category_name]=country&filter[posts_per_page]=-1

    I get returns above 100 when entered like that and can cap them at 111 etc.
    http://example.com/wp-json/wp/v2/posts/?filter[category_name]=country&filter[posts_per_page]=111

    For the modern WP scenarios the following function will allow you to give returns great than 99.

    add_filter( 'rest_post_collection_params', 'big_json_change_post_per_page', 10, 1 );
    function big_json_change_post_per_page( $params ) {
        if ( isset( $params['per_page'] ) ) {
            $params['per_page']['maximum'] = 200;
        }
        return $params;
    }
    
  2. As of WP 4.7 you can increase the upper limit of WP REST API requests by hooking into the following filter:

    rest_{$this->post_type}_collection_params

    This snippet should do the trick for posts:

    add_filter( 'rest_post_query', 'se35728943_change_post_per_page', 10, 2 );
    
    function se35728943_change_post_per_page( $args, $request ) {
        $max = max( (int) $request->get_param( 'custom_per_page' ), 200 );
        $args['posts_per_page'] = $max;    
        return $args;
    }
    

    Note: you can not use standard per_page argument (with value more then 100) in request – wp api will respond with error immediately (so the hook will not help). That’s in the above code wee use custom_per_page (you can use any another word).

    Similar filter for taxonomies: rest_{$this->taxonomy}_query

    Example:

    add_filter( 'rest_tags_query', 'se35728943_change_terms_per_page', 2, 10 );
    
    function se35728943_change_terms_per_page( $prepared_args, $request ){
        $max = max( 200, (int) $request->get_param( 'custom_per_page' ) );
    
        $prepared_args['number'] = $max;
        return $prepared_args;
    }
    
  3. Couldn’t get more than 10 with that syntax. Tried http://example.com/wp-json/wp/v2/posts?per_page=100 and worked up to 100.

  4. The bellow approch worked for me. I was able to retrieve posts from a site with 79 246 posts. I used pagination parameters . Within a loop, from 1 to TotalPages available. See the link for doc.

    http://mydomain/wp-json/wp/v2/posts?_embed&per_page=100&page=793
    

    per_page = 100 : means 100 posts max to be retrieved per page

    page = 793 : means i have 793 pages with 100 posts per page. the last page had only 46 posts

    A loop can then be used in a language of your choice.

  5. A simpler way that comply with protocol is to collect all responses, in sequence,
    and perform single setState() call. As follows: (error handling omitted for readability)

    componentDidMount() {
        var uri = "http://your-server";
        var totalPages = 0;
        var allResults = [];
    
        fetch(uri)
        .then(response => {
            totalPages = response.headers.get('X-WP-TotalPages');
            return response.json()})
        .then(results => {
            allResults = results;
            //console.log('Got results from server', results.length); 
            for (let i = 2; i <= totalPages ; i++){
                fetch(uri + "?page=" + i)
                .then(response => {return response.json()})
                .then( moreresults => {
                    allResults = allResults.concat( moreresults ); 
                });
            }
            this.setState({responses: allResults });
        });
    }
    
  6. In WordPress 4.9.6, I had to use rest_{$this->post_type}_query

    /* change amount of posts returned by REST API to 100 */
    function rest_posts_per_page( $args, $request ) {
        $max = max( (int)$request->get_param( 'per_page' ), 100 );
        $args['posts_per_page'] = $max;
        return $args;
    }
    add_filter( 'rest_post_query', 'rest_posts_per_page', 10, 2 );
    
  7. I hope this help, I’m using axios but is the same other

    async multipleRequests() {
                    let npage = 1;
                    let url = `/sites/mysite.com/wp-json/wp/v2/posts?page=${npage}&per_page=10`;
                    let { data } = await axios.get(url);
                    let tempdata = data;  
    
                    while (tempdata.length > 0) {
                        npage++;
                        let url = `/sites/mysyte.com/wp-json/wp/v2/media?page=${npage}&per_page=10`;
                        let { data } = await axios.get(url);                    
                        tempdata = data;
                    }
                }
    
  8. If you are planning on doing this with other parameters, you can also add categories etc as well. EG:

    https://www.website.com/wp-json/wp/v2/posts?categories=61&per_page=100
    
  9. It’s really possible to get more then 100 posts or terms (tags, categories).
    You should use rest_{$this->post_type}_query hook (for posts) or rest_{$this->taxonomy}_query hook for terms.
    But you have to know, that it’s impossible to pass a per_page arg in your GET request with more then 100 value. WP API will throw an error immediately (the hook will not help): per_page must be between 1 (inclusive) and 100 (inclusive) (with 400 http status).
    To get around this problem you should pass a per page value in another get argument. And after this to trace this value in your hook.
    So the code is:

    For posts

    add_filter( 'rest_post_query', 's976_rest_post_per_page', 2, 10 );
    function s976_rest_post_per_page( array $args, WP_REST_Request $request ) {
        $post_per_page = $request->get_param('s976_per_page') ? $request->get_param('s976_per_page') : 10;
        $args['posts_per_page'] = $post_per_page;
        return $args;
    }
    

    For terms

    add_filter( 'rest_category_query', 's976_rest_cats_per_page', 2, 10 );
    function s976_rest_cats_per_page( array $prepared_args, WP_REST_Request $request ){
        $cats_per_page = $request->get_param('s976_per_page') ? $request->get_param('s976_per_page') : 10;
        $prepared_args['number'] = $cats_per_page;
        return $prepared_args;
    }
    

    Of course, for this to work, you have to pass s976_per_page (with any value like 500, 99999) argument in GET request.

  10. I have been using this ‘s976_per_page’ bit of code successfully so many thanks,but It only returns the ‘publish’ tagged posts,..
    How could I get this to grab ALL statuses, or, alternatively, only a set / subset of statuses
    Many Thanks
    JMB

  11. According to documents, 100 is maximum to get. If you want more, use offsets and multiple requests. Example:

    $i              = 0;
    $check_for_more = true;
    
    while ( $check_for_more ) {
        $offset  = $i * 100;
        $url     = network_site_url( "/wp-json/wp/v2/office?order=asc&orderby=title&per_page=100&offset={$offset}" );
        $offices = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
    
        if ( $offices ) {
            if ( count( $offices ) < 100 ) {
                $check_for_more = false;
            }
            foreach ( $offices as $key => $office ) {
                // Do what you want
            }
        } else {
            $check_for_more = false;
        }
        $i ++;
    }
    
  12. Try this, this works fine (WP 5.8.1)

    add_filter( 'rest_{YOU_CPT}_collection_params', function ( $params, WP_Post_Type $post_type ) {
        if ( '{YOU_CPT}' === $post_type->name && isset( $params['per_page'] ) ) {
            $params['per_page']['maximum'] = PHP_INT_MAX;
        }
        return $params;
    }, 10, 2 );
    

Comments are closed.