# Pagination scripts

## Introduction

If a standard pagination type can't meet your pagination requirements, you can create a [custom script](/product-documentation/developer-hub/custom-scripting/pagination-scripts.md) and [apply this as the pagination method for endpoints](/product-documentation/developer-hub/connector-builder/building-your-own-connector/4-endpoints/endpoint-options/pagination/script-pagination.md).&#x20;

## Elements of a pagination script

Pagination scripts typically include:

* [Inputs](#inputs)
* [Outputs](#outputs)

### Inputs

Expected inputs must be inside the `payload` key of the `data` array. These are summarised below:

* [Request](#request)
* [Response](#response)&#x20;
* [Payload](#payload)

#### Request

An array/object representing the request parts for the current page:

<table data-full-width="false"><thead><tr><th width="150.89453125">Field</th><th width="200.54296875">Summary</th><th>Example</th></tr></thead><tbody><tr><td><code>body</code></td><td>A string version of the body.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['body'] = $payload['request']['body'];
</code></pre></td></tr><tr><td><code>headers</code></td><td>An array/object containing a key/value map of request headers. </td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['headers'] = $payload['request']['headers'];
</code></pre></td></tr><tr><td><code>method</code></td><td>The HTTP method. </td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php"> $returnPayload = [ 'has_next_page' => false, 'method' => 'GET' ];
</code></pre></td></tr><tr><td><code>url</code></td><td>The entire URL used in the request.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['url'] = $nextPage;
</code></pre></td></tr></tbody></table>

#### **Response**

An array/object containing the response parts returned from the request:

<table data-full-width="false"><thead><tr><th width="149.60546875">Field</th><th width="200.54296875">Summary</th><th>Example</th></tr></thead><tbody><tr><td><code>headers</code></td><td>An array/object containing a key/value map or response headers.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$links = $payload['response']['headers']['link'][0];
</code></pre></td></tr><tr><td><code>status_code</code></td><td>The HTTP response code. </td><td></td></tr></tbody></table>

#### **Payload**

The content saved as the payload. For example:

```php
$payload = json_decode($data['payload'], true);
```

### Outputs

If `has_next_page` is true, a JSON-encoded array/object should be returned (within the `payload` field) with the following:

<table data-full-width="false"><thead><tr><th width="155.69921875">Field</th><th width="200.54296875">Summary</th><th>Example</th></tr></thead><tbody><tr><td><code>has_next_page</code></td><td>Whether or not there is another page to be fetched.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['has_next_page'] = true;
</code></pre></td></tr><tr><td><code>url</code></td><td>The URL to use for the next page request.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['url'] = $nextPage;
</code></pre></td></tr><tr><td><code>headers</code></td><td>The headers to use for the next page request.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['headers'] = $payload['request']['headers'];
</code></pre></td></tr><tr><td><code>method</code></td><td>The HTTP method to use for the next page request.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['method'] = $payload['request']['method'];
</code></pre></td></tr><tr><td><code>body</code></td><td>The body content to use in the next request.</td><td><pre class="language-php" data-overflow="wrap"><code class="lang-php">$returnPayload['body'] = $payload['request']['body'];
</code></pre></td></tr></tbody></table>

## Pagination script example

The sample script below demonstrates `link header` functionality.

<details>

<summary><img src="/files/4iYjBn9HEfUXX4ZSP1vh" alt="" data-size="line"> Link header pagination script</summary>

{% code lineNumbers="true" %}

```php
 <?php

/**
 * Handler function.
 *
 * @param array $data [
 *      'payload'   => (string|null) the payload as a string|null
 *      'variables' => (array[string]string) any variables as key/value
 *      'meta'      => (array[string]string) any meta as key/value
 *      'flow'      => (array[mixed]) current flow data, including variables
 *    ]
 *
 * @return array $data Structure as above, plus 'logs' => (array[string]) Logs to be written to flow run log after script execution
 */


/**
 * Get next page url from link header string
 */
function getNext(string $linkHeaderString): string|null {
    if (!str_contains($linkHeaderString, 'rel="next"')) {
        return null;
    }

    $stringParts = explode(',', $linkHeaderString);

    $nextLinkString = count($stringParts) === 1 ? $stringParts[0] : $stringParts[1]; 

    $matches = [];

    preg_match_all('/<(.+)>;\s?rel="([A-z]*)"/', $nextLinkString, $matches);

    return $matches[1][0];
}

function handle($data)
{
    $payload = json_decode($data['payload'], true);

    $returnPayload = [
        'has_next_page' => false,
        'method' => 'GET'
    ];

    if (array_key_exists('response', $payload)) {
        if (array_key_exists('headers', $payload['response'])) {
            if (array_key_exists('link', $payload['response']['headers'])) {
                /** check if the header contains the next page link
                    Header will be in the format:

                    <https://custom-peaks-1.myshopify.com/admin/api/2023-04/customers.json?limit=50&page_info=eyJkaXJlY3Rpb24iOiJwcmV2IiwibGFzdF9pZCI6NzIyMjM0MzA0MTE4MiwibGFzdF92YWx1ZSI6MTcwMzE2NDgxMDAwMH0>; rel="previous", <https://custom-peaks-1.myshopify.com/admin/api/2023-04/customers.json?limit=50&page_info=eyJkaXJlY3Rpb24iOiJuZXh0IiwibGFzdF9pZCI6Njg2MjY2MjUzMzI3OCwibGFzdF92YWx1ZSI6MTY4NjM1MDU1OTAwMH0>; rel="next"
                */
                $links = $payload['response']['headers']['link'][0];

                $nextPage = getNext($links);

                if ($nextPage) {
                    $returnPayload['has_next_page'] = true;
                    $returnPayload['url'] = $nextPage;
                    $returnPayload['body'] = $payload['request']['body'];
                    $returnPayload['headers'] = $payload['request']['headers'];
                }
            }
        }
    }


    return [
        'payload' => json_encode($returnPayload)
    ];
}
```

{% endcode %}

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.wearepatchworks.com/product-documentation/developer-hub/custom-scripting/pagination-scripts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
