Skip to main content

Pagination

Pagination helps you efficiently navigate, sort, and filter large collections of data without fetching everything at once. This is especially useful for endpoints like:

Filtering

Filtering is another way to efficiently navigate and filter large collections of data without fetching everything at once.

Whenever pagination is applied, then so is filtering.

Filtering allows you to filter your fetched objects through specific features or conditions like queries.

Whenever an endpoint may return many items, Stream uses a consistent pagination and filtering structure across all list responses.


Request Parameters

Pagination Parameters

You can control pagination using the following query parameters:

ParameterTypeDescription
pageintPage number starting from 1.
limitintNumber of items per page. Maximum: 100.
sort_fieldstringField used to sort the results.
sort_directionstringEither "asc" or "desc" depending on sorting direction.

By default, sort_field is created_at and sort_direction is desc.

GET api/v2/products?page=1&limit=20&sort_field=created_at&sort_direction=desc

#Filtering allows you to query objects based on specific attributes. When you apply filters, the pagination metadata in the response will reflect the total count of items matching your filter, not the total database count.

ParameterTypeDescription
search_termstringA generic query string. The API searches relevant fields (e.g., names, IDs, descriptions) for matches.
Field Specificstring / arraySpecific attributes depending on the resource (e.g., invoice_id, statuses, currency).

Note on Array Filters: Some parameters, like statuses, accept multiple values. In the query string, this appears as repeating keys: statuses=PENDING&statuses=PROCESSING

For example, the List Payments endpoint takes filtering queries like invoice_id and statuses to filter down the returned payments.

Example query:

GET api/v2/payments?page=1&limit=20&invoice_id=73b89d47-1bb1-443c-9a4c-f0ee23e22191&statuses=PENDING&statuses=PROCESSING

Pagination Response Structure

Paginated responses include a pagination object that provides metadata about the current, previous, and next pages.

FieldDescription
total_countNumber of objects returned in the current page.
max_pageMaximum page number available.
current_pagePage you are currently on.
limitPage size (echoes your request, capped at 100).
has_next_pageWhether another page exists after this one.
has_previous_pageWhether a page exists before this one.

Example response snippet:

{
"data": [...],
"pagination": {
"total_count": 20,
"max_page": 12,
"current_page": 1,
"limit": 20,
"has_next_page": true,
"has_previous_page": false
}
}

Examples (Python)

Below are practical examples using Python's requests library.

1. Basic Pagination

Fetching the first page of results with a custom limit.

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://stream-app-service.streampay.sa/api/v2/products"

response = requests.get(
BASE_URL,
headers={"x-api-key": API_KEY},
params={
"page": 1,
"limit": 20
}
)

data = response.json()
print(f"Showing page {data['pagination']['current_page']} of {data['pagination']['max_page']}")

2. Global Search Filtering

Using the search_term to find items matching a specific string (e.g., a customer name or partial ID).

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://stream-app-service.streampay.sa/api/v2/customers"

response = requests.get(
BASE_URL,
headers={"x-api-key": API_KEY},
params={
"search_term": "JOHN DOE", # Searches for customer with that name
"limit": 10
}
)

results = response.json()["data"]
print(f"Found {len(results)} matches for 'Al-Faisaliah'")

3. Advanced Filtering (Lists & Specific Fields)

Filtering by a specific invoice_id and multiple statuses. Note how the list of statuses is passed to the params dictionary.

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://stream-app-service.streampay.sa/api/v2/payments"

# To filter by multiple statuses, pass them as a list
payload_filters = {
"page": 1,
"limit": 50,
"invoice_id": "73b89d47-1bb1-443c-9a4c-f0ee23e22191",
"statuses": ["PENDING", "PROCESSING"] # Requests handles this as statuses=PENDING&statuses=PROCESSING
}

response = requests.get(
BASE_URL,
headers={"x-api-key": API_KEY},
params=payload_filters
)

payments = response.json()["data"]
for p in payments:
print(f"Payment ID: {p['id']} | Status: {p['status']}")

4. Iterating Through All Pages

A robust pattern to fetch every item available.

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://stream-app-service.streampay.sa/api/v2/products"

page = 1
all_products = []

while True:
response = requests.get(
BASE_URL,
headers={"x-api-key": API_KEY},
params={"page": page, "limit": 100} # Maximize limit to reduce requests
)

body = response.json()
all_products.extend(body["data"])

# Stop if there are no more pages
if not body["pagination"]["has_next_page"]:
break

page += 1

print(f"Successfully fetched {len(all_products)} products.")