Paginating Trello Board Cards with the REST API: A Reliable Export Pattern
Learn how to reliably paginate Trello's REST API card endpoints using cursor‑based before/since parameters, avoid missing or duplicate cards, and handle rate limits in export scripts.
22 Jul 2026, 10:49 UTC

Problem
Exporting or syncing all cards from a large Trello board fails when a single request returns only the first 1000 items. The API uses cursor‑based pagination (the before and since parameters) rather than offset/limit, so a script must walk backward through card IDs to retrieve every card without gaps or duplicates.
Prerequisites
- A Trello API key and a user token with
readscope for the target board. - Network access to
https://api.trello.comfrom the machine running the script. - Basic familiarity with HTTP GET requests (e.g.,
curl,httpie, or a language‑specific HTTP client). - Board ID (the short alphanumeric string visible in the board URL).
Procedure
1. Choose a safe page size
The endpoint GET /1/boards/{id}/cards accepts limit up to 1000. Use a smaller value (e.g., 200) to reduce latency and the chance of hitting rate limits.
2. Initial request – newest cards first
curl -G "https://api.trello.com/1/boards/{BOARD_ID}/cards" \
--data-urlencode "key={API_KEY}" \
--data-urlencode "token={TOKEN}" \
--data-urlencode "limit=200" \
--data-urlencode "fields=id,name,dateLastActivity" \
--data-urlencode "actions=none"
Run this in a terminal where curl is installed. The response is a JSON array of card objects, newest first.
3. Extract the cursor for the next page
Take the id of the last element in the returned array (the oldest card in that page). That ID becomes the before value for the next call.
4. Loop until the page is smaller than the requested limit
#!/usr/bin/env bash
# paginate_trello_cards.sh
BOARD_ID="{BOARD_ID}"
KEY="{API_KEY}"
TOKEN="{TOKEN}"
LIMIT=200
BEFORE=""
while true; do
QUERY=(--data-urlencode "key=$KEY" --data-urlencode "token=$TOKEN" \
--data-urlencode "limit=$LIMIT" --data-urlencode "fields=id,name,dateLastActivity" \
--data-urlencode "actions=none")
if [[ -n "$BEFORE" ]]; then
QUERY+=(--data-urlencode "before=$BEFORE")
fi
RESPONSE=$(curl -sS -G "https://api.trello.com/1/boards/$BOARD_ID/cards" "${QUERY[@]}")
COUNT=$(echo "$RESPONSE" | jq 'length')
echo "$RESPONSE" >> all_cards.json
if (( COUNT < LIMIT )); then
break
fi
BEFORE=$(echo "$RESPONSE" | jq -r '.[-1].id')
sleep 0.2 # polite back‑off to avoid 429
done
Save the script, make it executable (chmod +x paginate_trello_cards.sh), and run it. Each iteration appends a page to all_cards.json.
5. Optional forward pass for cards created during the export
Because the loop walks backward, any card added after the first request will not appear. After the backward walk finishes, run a second pass using since with the ID of the newest card you captured:
SINCE=$(jq -r '.[0].id' all_cards.json)
curl -G "https://api.trello.com/1/boards/{BOARD_ID}/cards" \
--data-urlencode "key={API_KEY}" \
--data-urlencode "token={TOKEN}" \
--data-urlencode "since=$SINCE" \
--data-urlencode "fields=id,name,dateLastActivity" \
--data-urlencode "actions=none" >> all_cards.json
Verification
- Spot‑check page size: Run a single request with
limit=5and confirm exactly five cards return. Then use the last card’s ID asbeforeand verify the next page contains older, non‑overlapping cards. - Max‑limit guard: On a board known to have >1000 cards, request
limit=1000and ensure the response never exceeds 1000 items. - Auth error path: Temporarily invalidate the token and confirm a
401 Unauthorizedresponse; your script should surface this and stop.
Limitations and Recovery
- Hard limit: No single request can return more than 1000 cards; the script must paginate.
- Cursor semantics:
beforeandsinceaccept card IDs, not timestamps. Supplying a date string yields an error. - Concurrent changes: Cards created while the backward loop runs are missed. The forward
sincepass mitigates this but cannot capture cards deleted between the two passes. - Rate limiting: HTTP 429 responses require exponential back‑off. The example includes a minimal
sleep 0.2; production code should implement a full retry strategy. - Rollback: This operation is read‑only; no state is changed on Trello, so no rollback is needed.
Practical Check
After the script finishes, count the unique card IDs in all_cards.json and compare with the board’s card total shown in the UI (Board → Menu → More → Print and Export → JSON). A match within a few cards (accounting for concurrent edits) confirms a complete export.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.