The Code
I've created a PHP class to communicate with Instagram's API. I am using a private function called api_request (shown below) to communicate with Instagram's API:
private function api_request( $request = null ) {
    if ( is_null( $request ) ) {
        $request = $this->request["httpRequest"];
    }
    $body = wp_remote_retrieve_body( wp_remote_get( $request, array(
                "timeout" => 10,
                "content-type" => "application/json"
            )
        )
    );
    try {
        $response = json_decode( $body, true );
        $this->data["pagination"] = $response["pagination"]["next_url"];
        $this->data["response"] = $response["data"];
        $this->setup_data( $this->data );
    } catch ( Exception $ex ) {
        $this->data = null;
    }
}
These two lines of code...
$this->data["pagination"] = $response["pagination"]["next_url"];
$this->data["response"] = $response["data"];
...sets up my data within this array:
private $data = array (
    "response"      => null,
    "pagination"    => null,
    "photos"        => array()
);
The Problem
Whenever I request the next page, with the following function:
public function pagination_query() {
    $this->api_request( $this->data["pagination"] );
    $output = json_encode( $this->data["photos"] );
    return $output;
}
Instagram gives me the first page, over and over and over gain. Any idea what the problem is here?
Update #1
I realized that because my setup_data function (used in api_request function) pushes my photo objects onto the end of my $this->data["photos"] array:
private function setup_data( $data ) {
    foreach ( $data["response"] as $obj ) {
        /* code that parses the api, goes here */
        /* pushes new object onto photo stack */
        array_push( $this->data["photos"], $new_obj );
    }
}
...it is necessary to create an empty array, when requesting a new page:
public function pagination_query() {
    $this->data["photos"] = array(); // kicks out old photo objects
    $this->api_request( $this->data["pagination"] );
    $output = json_encode( $this->data["photos"] );
    return $output;
}
I'm able to retrieve the second page but all subsequent pagination_query calls only return the second page. Any ideas what could be wrong?
Update #2
I discovered that using a while statement, to make the api_request function call itself, allows to me retrieve page after page just fine:
private function api_request( $request = null ) {
    if ( is_null( $request ) ) {
        $request = $this->request["httpRequest"];
    }
    $body = wp_remote_retrieve_body( wp_remote_get( $request, array(
                "timeout" => 18,
                "content-type" => "application/json"
            )
        )
    );
    try {
        $response = json_decode( $body, true );
        $this->data["response"] = $response["data"];
        $this->data["next_page"] = $response["pagination"]["next_url"];
        $this->setup_data( $this->data );
        // while state returns page after page just fine
        while ( count( $this->data["photos"] ) < 80 ) {
            $this-> api_request( $this->data["next_page"] );
        }
    } catch ( Exception $ex ) {
        $this->data = null;
    }
}
However, this doesn't fix my pagination_query function and it appears as if my try-catch block is creating a closure and I'm not really sure what to make of this.
                        
In your first snippet of code you have:
Note two keys:
responseandnext_pageThen in your second snippet you have:
Now
next_pageispaginationNow if you use
But you are using
$this->data["next_page"] = $response["pagination"]["next_url"];of course you will not get the right results.In any case try to var_dump the content of of your $request:
If you have a debbugger also check inside api_request which is the url passed each time