Pagination
One endpoint in the 4N NextDay API is paginated: the order list. This guide covers how to navigate it.
What paginates
| Endpoint | Paginated? |
|---|---|
GET /orders | Yes — page and per_page query parameters, items + meta in data |
GET /localities | No — data is the full array |
GET /regions | No — data is the full array |
GET /services | No — data is the full array |
Everything below applies to GET /orders only.
Pagination Parameters
- Name
page- Type
- integer
- Description
The page number to retrieve. Default:
1
- Name
per_page- Type
- integer
- Description
Number of items per page. Default:
15, Min:1, Max:100. Values outside this range return a422validation error onper_page.
Paginated Response Structure
The response puts an items array inside data, along with a meta object containing pagination information:
- Name
current_page- Type
- integer
- Description
The current page number.
- Name
from- Type
- integer|null
- Description
The index of the first item on this page (
nullwhen the page is empty).
- Name
to- Type
- integer|null
- Description
The index of the last item on this page (
nullwhen the page is empty).
- Name
last_page- Type
- integer
- Description
The total number of pages.
- Name
per_page- Type
- integer
- Description
Items per page.
- Name
total- Type
- integer
- Description
Total number of items across all pages.
Orders are sorted newest first.
Paginated response
{
"success": true,
"message": "Orders retrieved successfully",
"data": {
"items": [
{
"id": 12346,
"tracking_number": "4N202502030002"
// ...
},
{
"id": 12345,
"tracking_number": "4N202502030001"
// ...
}
],
"meta": {
"current_page": 2,
"from": 16,
"to": 30,
"last_page": 5,
"per_page": 15,
"total": 73
}
},
"timestamp": "2025-02-03T10:00:00.000000Z"
}
Example: Fetching Orders
# First page (default)
curl "https://api.4nortes.app/api/v1/orders" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
# Specific page with custom page size
curl "https://api.4nortes.app/api/v1/orders?page=2&per_page=25" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Iterating Through All Pages
Here's how to iterate through all pages of results:
async function getAllOrders() {
const allOrders = []
let page = 1
let hasMore = true
while (hasMore) {
const response = await fetch(
`https://api.4nortes.app/api/v1/orders?page=${page}&per_page=100`,
{
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json',
},
}
)
if (!response.ok) {
throw new Error(`Failed to load page ${page}: HTTP ${response.status}`)
}
const result = await response.json()
allOrders.push(...result.data.items)
hasMore = page < result.data.meta.last_page
page++
}
return allOrders
}
def get_all_orders():
all_orders = []
page = 1
while True:
response = requests.get(
'https://api.4nortes.app/api/v1/orders',
headers={'Authorization': f'Bearer {token}'},
params={'page': page, 'per_page': 100}
)
response.raise_for_status()
result = response.json()
all_orders.extend(result['data']['items'])
if page >= result['data']['meta']['last_page']:
break
page += 1
return all_orders
Best Practices
-
Use appropriate page sizes: Request only what you need. Smaller page sizes mean faster responses.
-
Don't poll the list for status changes: Use webhooks to be told when an order moves, and the Tracking API for a single order.
-
Handle empty results: Always check if
itemsis empty before processing.fromandtoarenullon an empty page. -
Respect rate limits: The API allows 100 requests per minute per account. A full export at
per_page=100costs one request per 100 orders — add a short delay between pages for very large accounts.
// Add delay between pagination requests
async function fetchWithDelay(page) {
const response = await fetch(
`https://api.4nortes.app/api/v1/orders?page=${page}&per_page=100`,
{ headers: { 'Authorization': `Bearer ${token}` } }
)
await new Promise(resolve => setTimeout(resolve, 100)) // 100ms delay
return response.json()
}