# Pagination

Our API supports **cursor-based pagination**, inspired by the JSON:API pagination specification. This approach is efficient and scalable for large datasets.

Each paginated response contains a `data` array and `links` for navigating through pages.

***

### 📦 Response Format

```json
{
  "data": <...>,
  "links": {
    "self": "https://api.example.com/resources?cursor=abcdef",
    "next": "https://api.example.com/resources?cursor=ghijkl"
  }
}
```

#### 🔗 `links.self`

URL for the current page. Safe to cache or re-fetch.

#### 🔗 `links.next`

URL for the next page. If absent or `null`, you've reached the end.

#### 🧭 `cursor`

A **cursor** is an opaque string provided by the server to mark a position in the dataset. You must use it exactly as returned.\
**Do not attempt to decode or generate it manually.**

***

### 🔐 Authentication Required

Before making any paginated requests, make sure your client is authenticated properly.

➡️ **See the Authentication section for details on required headers.**

***

{% tabs %}
{% tab title="cURL" %}

#### 🟡 cURL

```bash
curl "https://api.example.com/resources" \
  -H "X-API-KEY: your-api-key" \
  -H "X-API-SECRET: your-api-secret"
```

Then use the `links.next` URL:

```bash
curl "https://api.example.com/resources?page[cursor]=ghijkl" \
  -H "X-API-KEY: your-api-key" \
  -H "X-API-SECRET: your-api-secret"
```

{% endtab %}

{% tab title="Typescript" %}

#### 🟦 TypeScript (e.g. in a React or Node.js app)

```ts
async function fetchPage(url: string) {
  const res = await fetch(url, {
    headers: {
      'X-API-KEY': 'your-api-key',
      'X-API-SECRET': 'your-api-secret',
    },
  });
  const body = await res.json();

  console.log('Current page:', body.data);

  if (body.links?.next) {
    console.log('Next page URL:', body.links.next);
    // await fetchPage(body.links.next);
  }
}

fetchPage('https://api.example.com/resources');
```

{% endtab %}

{% tab title="Java" %}

#### 🟠 Java (with `HttpClient` and Jackson)

```java
HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();

void fetchPage(String url) throws IOException, InterruptedException {
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(url))
        .header("X-API-KEY", "your-api-key")
        .header("X-API-SECRET", "your-api-secret")
        .GET()
        .build();

    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    JsonNode json = mapper.readTree(response.body());

    System.out.println("Current page: " + json.get("data"));

    JsonNode next = json.path("links").path("next");
    if (!next.isMissingNode()) {
        System.out.println("Next page URL: " + next.asText());
        // fetchPage(next.asText());
    }
}
```

{% endtab %}

{% tab title=".NET" %}

#### 🟦 .NET (C# with `HttpClient`)

```csharp
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

async Task FetchPageAsync(string url)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Add("X-API-KEY", "your-api-key");
    client.DefaultRequestHeaders.Add("X-API-SECRET", "your-api-secret");

    var response = await client.GetStringAsync(url);

    using var doc = JsonDocument.Parse(response);
    var root = doc.RootElement;

    Console.WriteLine("Current page: " + root.GetProperty("data"));

    if (root.TryGetProperty("links", out var links) &&
        links.TryGetProperty("next", out var next))
    {
        Console.WriteLine("Next page URL: " + next.GetString());
        // await FetchPageAsync(next.GetString());
    }
}
```

{% endtab %}
{% endtabs %}

### ✅ Best Practices

* **Always use the `links.next` URL** for pagination.
* **Never parse or construct cursors manually.**
* **Stop paginating** when `links.next` is missing or `null`.
* **Ensure authentication headers are included** — see the Authentication section.


---

# 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://docs.getcakewalk.io/open-api-and-mcp/pagination.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.
