Skip to main content
Always paginate. Even if your test environment has 10 users, production might have 10,000. The SDK handles pagination orchestration - use it from day one.

Basic pattern

Every List(), Entitlements(), and Grants() method returns a next page token:
The SDK calls your method repeatedly until you return an empty token. Your job: fetch and convert one page at a time.
Use the API’s next token for termination, not result count. Some APIs return empty pages before the final page, so len(results) < pageSize isn’t reliable. Return "" only when the API signals no more pages.

Pagination strategies

APIs paginate results differently. Your connector adapts the token to whatever the API expects:

Cursor-based (most modern APIs)

Offset-based (traditional REST)

LDAP paging (Active Directory)

Nested pagination with Bag

When you have hierarchies, you often need to paginate at multiple levels: “page through orgs, and for each org, page through repos.” The SDK’s pagination.Bag handles this.

How Bag works

The Bag acts as a stack for managing complex pagination state:
Key methods:
  • Push(state PageState) - Push new pagination state onto stack
  • Pop() *PageState - Pop current state, make top of stack current
  • Next(pageToken string) - Update current state with new page token
  • Current() *PageState - Get current state (may be nil)
  • Marshal() (string, error) - Serialize state to opaque token
  • Unmarshal(token string) error - Restore state from token

Example: paginating repos within orgs

Bag.Current() nil safety: The Bag starts empty. Current() returns nil until you Push() a state. Always check for nil before accessing fields.

Multi-level nested pagination

For deeper hierarchies (org -> team -> members), push and pop states:

Modeling hierarchies

Real systems often have deep hierarchies. The Baton model handles these naturally: declare parent-child relationships and the SDK walks the tree for you.

Two mechanisms connect parent and child

1. Parent declares child types via ChildResourceType annotation:
2. Child references parent via ParentResourceID:
When the SDK calls List() for child resources, it passes the parent’s ResourceId so you can scope your API calls.

Example: GitHub hierarchy

Organization builder:
Repository builder - receives parent org in List():

When to use hierarchies vs flat models

Common hierarchy mistakes

Pagination invariants

The SDK enforces invariants to catch common bugs:
  • Token must progress: Returning the same token you received causes an error. This prevents infinite loops.
  • Empty token means done: Return "" when there are no more pages.
  • Consistent page sizes: While not enforced, use consistent page sizes for predictable behavior.
Test with small page sizes (10-20 items) during development to verify pagination works correctly before testing with production-sized datasets.