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:
| Parameter | Type | Description |
|---|---|---|
page | int | Page number starting from 1. |
limit | int | Number of items per page. Maximum: 100. |
sort_field | string | Field used to sort the results. |
sort_direction | string | Either "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.
| Parameter | Type | Description |
|---|---|---|
search_term | string | A generic query string. The API searches relevant fields (e.g., names, IDs, descriptions) for matches. |
| Field Specific | string / array | Specific 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.
| Field | Description |
|---|---|
total_count | Number of objects returned in the current page. |
max_page | Maximum page number available. |
current_page | Page you are currently on. |
limit | Page size (echoes your request, capped at 100). |
has_next_page | Whether another page exists after this one. |
has_previous_page | Whether 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.")