---
title: "Pagination"
description: "One page, every page, or one item at a time."
url: "https://openemail.uk/docs/csharp/pagination"
area: "C#"
category: "Getting started"
---

# Pagination

One page, every page, or one item at a time.

## One page

**page.cs**

```
var page = await client.Threads.ListAsync(folder: "inbox", limit: 25);

foreach (var thread in page)
{
    Console.WriteLine(thread["id"]);
}

if (page.HasMore)
{
    var next = await client.Threads.ListAsync(folder: "inbox", limit: 25, cursor: page.NextCursor);

    Console.WriteLine(next.Count);
}
```

A `ListAsync` method returns a `Page` with `Items`, `HasMore` and `NextCursor`, and `foreach` walks its items. Pass `NextCursor` back as `cursor:`, with the same filters, to read the next page.

## Every page

**all.cs**

```
var failed = await client.Emails.ListAllAsync(status: new[] { "failed" });

Console.WriteLine($"{failed.Count} messages failed");
```

A `ListAllAsync` method follows the cursor to the end and returns every item in one list. A failure on any page fails the whole call.

## One item at a time

**iterate.cs**

```
await foreach (var contact in client.Contacts.IterateAsync(limit: 100))
{
    if ((string?)contact["email"] == "ada@example.com")
    {
        break;
    }
}

await foreach (var entry in client.Emails.IterateEventsAsync("msg_3f9a1c07d2b84e6a9c5b1f20"))
{
    Console.WriteLine(entry["type"]);
}
```

An `IterateAsync` method returns an `IAsyncEnumerable<JsonObject>`, which asks for the next page only when the loop reaches it, so a `break` stops the requests. Every list that pages has all three, named after the list they walk: `ListAllEventsAsync` and `IterateEventsAsync` beside `ListEventsAsync`.

> A walk stops when the API repeats a cursor it has already followed, so it can never loop for ever.
