Pagination
Cursor pagination on GET /v1/shipments. Follow nextCursor until it is null.
GET /v1/shipments returns one page at a time, most recently updated first:
JSON
{
"data": [{ "reference": "QB51907", "status": "Active", "…": "…" }],
"nextCursor": "eyJ1IjoiMjAyNi0wOS0xNVQyMTo0ODowMFoiLCJyIjoiUUI1MTkwNyJ9"
}| Parameter | Meaning |
|---|---|
limit | Page size, 1–100. Default 50. |
cursor | The nextCursor value of the previous response, unchanged. |
Rules
- Next page: repeat the request with the same filters and
cursorset to the previousnextCursor. nextCursor: nullmeans this is the last page.- Cursors are opaque.
- An unusable cursor returns
400 invalid_cursor. Restart withoutcursor. - There is no total count and no page numbers.
- A shipment that changes while you paginate moves to the front, so it can appear twice or be skipped within one run. Upsert by
referenceand poll withupdatedSince.
Filters
All filters are optional and combine with AND.
| Parameter | Meaning |
|---|---|
status | One of Active, Delivered, Cancelled. Repeat it to match any of several: ?status=Active&status=Delivered. |
updatedSince | ISO 8601 timestamp. Shipments whose updatedAt is at or after it. |
createdSince | ISO 8601 timestamp. Shipments whose createdAt is at or after it. |
tag | Exact match on one of the customer's own tags (PO numbers). |
search | Free text across the reference, tags, master bill / air waybill numbers, container numbers, and Amazon FBA and reference IDs. |
An invalid value returns 400 invalid_parameter naming the parameter; the hint lists the allowed values.
Read every page
TypeScript
const BASE_URL = 'https://api.gocubic.io/v1';
const headers = { Authorization: `Bearer ${process.env.CUBIC_API_KEY}` };
const shipments = [];
let cursor: string | null = null;
do {
const url = new URL(`${BASE_URL}/shipments`);
url.searchParams.set('limit', '100');
url.searchParams.set('status', 'Active');
if (cursor) url.searchParams.set('cursor', cursor);
const response = await fetch(url, { headers });
if (!response.ok) throw new Error(JSON.stringify(await response.json()));
const page = await response.json();
shipments.push(...page.data);
cursor = page.nextCursor;
} while (cursor);
console.log(`${shipments.length} active shipments`);Python
import os
import requests
BASE_URL = "https://api.gocubic.io/v1"
headers = {"Authorization": f"Bearer {os.environ['CUBIC_API_KEY']}"}
shipments = []
params = {"limit": 100, "status": "Active"}
while True:
response = requests.get(f"{BASE_URL}/shipments", headers=headers, params=params, timeout=30)
response.raise_for_status()
page = response.json()
shipments.extend(page["data"])
if page["nextCursor"] is None:
break
params["cursor"] = page["nextCursor"]
print(f"{len(shipments)} active shipments")The client in Recipes wraps this loop and adds 429 backoff.