Guides

Pagination

Lists return one page at a time. Ask for a page with limit, and while pagination.hasMore is true call again with the nextCursor you were given.

Your system
API
  1. GET /api/v1/orders?limit=50

    limit defaults to 50 and is at most 500. Add includeTotal=true to get pagination.total.

  2. data and pagination { hasMore: true, nextCursor }

  3. While hasMore is true:

  4. GET /api/v1/orders?limit=50&cursor=<nextCursor>

    The same limit and sort: a cursor is bound to both. The cursor is opaque; do not build it.

  5. Next page

  6. hasMore: false: you have read every page.

The pagination loop
  1. Request the first page

    Send the list request with limit: 1 to 500, 50 by default. Do not send a cursor.

  2. Read the page

    Take the records from data. pagination.hasMore tells you whether more results exist.

  3. Ask for the next one

    While hasMore is true, call again with cursor set to pagination.nextCursor, and the same limit and filters.

  4. Stop

    On the last page hasMore is false and nextCursor is null.

# Needs curl and jq. Prints one order per line.
base="${FILMO_BASE_URL:-https://app.filmo.io}"
cursor=""
while :; do
  # Keep limit and sort identical on every page.
  set -- --data-urlencode "limit=100" --data-urlencode "sort=createdAt"
  [ -n "$cursor" ] && set -- "$@" --data-urlencode "cursor=$cursor"

  page="$(curl -sS --fail-with-body -G "$base/api/v1/orders" \
    -H "Authorization: Bearer $FILMO_API_KEY" "$@")" || { echo "$page" >&2; exit 1; }

  echo "$page" | jq -c '.data[]'
  cursor="$(echo "$page" | jq -r 'if .pagination.hasMore then .pagination.nextCursor else "" end')"
  [ -n "$cursor" ] || break
done
PropertyTypeMeaning
nextCursorstring or nullOpaque cursor of the next page. null when there are no more results.
hasMorebooleanWhether more results exist beyond this page.
totalintegerThe number of results that match the filters across all pages. Present only when the request sets includeTotal to true.

Following the cursor can skip records

The cursor marks a position in the result. If a record you have already read is updated or deleted while you are still paging, the records after it shift, and one at the boundary of a page can be missed; it is not returned again in that pass. A pass that tolerates this, such as a one-off export, can follow the cursor. The cursor is a position, not a snapshot: if you sort by updatedAt and a record is updated while you page, it moves to the end of an ascending pass (and the following records may be skipped) or to the front of a descending one (and you may read a record twice). To keep another system in step with Filmo, do not rely on the cursor: read time windows with the updated* filters instead. Syncing data explains how.

  • Guides

    Filtering and sorting

    Most lists accept sort and the created* and updated* time filters, many accept list-valued filters such as statuses, and some accept q for free-text search. The examples use the orders list.

  • Guides

    Syncing data

    Filmo v1 does not send webhooks, so you keep another system in step by polling: read what changed in half-open time windows, and run a separate sweep to find what was deleted. Do not follow the pagination cursor to decide what changed or what disappeared.

  • Guides

    Rate limits

    Each API key has 120 requests per minute, and the three availability checks share their own quota of 30 per minute. Past a limit the API answers 429 with Retry-After.