Skip to content
StraventaDocs
Guides

Pagination

Cursor-free page-based pagination with envelope format, limit clamping, and search support

Pagination

All list endpoints in the 505pay API use page-based pagination. Results are returned in a consistent envelope alongside metadata for building navigation controls.

Response envelope

{
  "payments": [
    { "id": "01j...", "amount": 150000, "status": "completed" },
    { "id": "01j...", "amount": 75000, "status": "pending" }
  ],
  "total": 243,
  "page": 2,
  "limit": 20,
  "total_pages": 13
}
FieldTypeDescription
<resource>arrayArray of resource objects for the current page
totalintegerTotal number of records matching the query
pageintegerCurrent page number (1-based)
limitintegerNumber of records per page (clamped to [1, 100])
total_pagesintegerTotal number of pages: ceil(total / limit)

Query parameters

GET /v1/payments?page=2&limit=20&search=budi
ParameterTypeDefaultDescription
pageinteger1Page number to retrieve (1-based)
limitinteger20Records per page; clamped to [1, 100] server-side
searchstringFree-text search across searchable fields (name, email, reference ID)

The limit parameter is clamped server-side to [1, 100]. Requesting limit=500 returns at most 100 records.

Fetching all pages

#!/bin/bash
PAGE=1
LIMIT=100
TOTAL_PAGES=1  # Will be updated after the first request

while [ "$PAGE" -le "$TOTAL_PAGES" ]; do
  RESPONSE=$(curl -s "https://sandbox.505pay.link/v1/payments?page=$PAGE&limit=$LIMIT" \
    -H "Authorization: Bearer $ACCESS_TOKEN")

  # Update total pages from first response
  TOTAL_PAGES=$(echo "$RESPONSE" | jq '.total_pages')

  # Process current page
  echo "$RESPONSE" | jq '.payments[]'

  PAGE=$((PAGE + 1))
done
interface PaginatedResponse<T> {
  total: number;
  page: number;
  limit: number;
  total_pages: number;
  [key: string]: T[] | number;
}

async function fetchAllPages<T>(
  endpoint: string,
  resourceKey: string,
  token: string,
  limit = 100,
): Promise<T[]> {
  const results: T[] = [];
  let page = 1;
  let totalPages = 1;

  do {
    const res = await fetch(
      `${endpoint}?page=${page}&limit=${limit}`,
      { headers: { Authorization: `Bearer ${token}` } },
    );

    if (!res.ok) throw new Error(`HTTP ${res.status}`);

    const data = await res.json() as PaginatedResponse<T>;
    totalPages = data.total_pages;
    results.push(...(data[resourceKey] as T[]));
    page++;
  } while (page <= totalPages);

  return results;
}

// Usage
const allPayments = await fetchAllPages(
  'https://sandbox.505pay.link/v1/payments',
  'payments',
  accessToken,
);
console.log(`Fetched ${allPayments.length} payments`);
import requests

def fetch_all_pages(endpoint: str, resource_key: str, access_token: str, limit: int = 100):
    results = []
    page = 1
    total_pages = 1

    while page <= total_pages:
        response = requests.get(
            endpoint,
            params={'page': page, 'limit': limit},
            headers={'Authorization': f'Bearer {access_token}'},
            timeout=30,
        )
        response.raise_for_status()
        data = response.json()

        total_pages = data['total_pages']
        results.extend(data[resource_key])
        page += 1

    return results

# Usage
all_payments = fetch_all_pages(
    'https://sandbox.505pay.link/v1/payments',
    'payments',
    access_token,
)
print(f'Fetched {len(all_payments)} payments')

Searching

Append ?search=<term> to filter results across searchable fields. Search is case-insensitive and matches partial strings.

# Find payments by customer email
curl "https://sandbox.505pay.link/v1/[email protected]&limit=20" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# Find payments by reference ID prefix
curl "https://sandbox.505pay.link/v1/payments?search=INV-2026&limit=50" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Searchable fields vary by resource — consult the individual endpoint reference for details.

Tips

  • Use limit=100 when fetching all records to minimize round trips.
  • Cache total_pages from the first response rather than checking it after every page.
  • Combine search with pagination — total in the response reflects filtered results.
  • For real-time dashboards, fetch only the first page (page=1) and display total for the summary count without loading all records.

Was this page helpful?

On this page