{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Pagination","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"pagination","__idx":0},"children":["Pagination"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["List endpoints in the Rho API return results in pages using ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["opaque cursor-based pagination"]},". You ask for a page size, the response includes the items plus a cursor to the next page, and you follow that cursor to fetch each subsequent page."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cursors are stable across changes to the underlying data: new items inserted while you are iterating will not shift existing pages or cause items to be skipped or duplicated."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"request-parameters","__idx":1},"children":["Request parameters"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every list endpoint accepts the same two pagination parameters as query string values:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Notes"},"children":["Notes"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page_size"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["integer"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["How many items to return. Each endpoint defines its own minimum, maximum, and default - see the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/v1/openapi"},"children":["API Reference"]},". Values outside the allowed range return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400 Bad Request"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page_token"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Opaque cursor returned as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["next_page_token"]}," by a previous response. Omit to fetch the first page."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cursors are opaque - pass back exactly the string you received."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A token returned by one endpoint is only valid for that ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["same endpoint with the same filters and sort order"]},". Using a cursor with changed filters or sorting will result in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400 Bad Request"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"response-shape","__idx":2},"children":["Response shape"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every paginated response wraps the items in a top-level array and includes a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," object:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"transactions\": [\n    { \"id\": \"…\", \"amount\": { \"amount\": 1299, \"currency\": \"USD\" }, \"…\": \"…\" },\n    { \"id\": \"…\", \"amount\": { \"amount\": 4500, \"currency\": \"USD\" }, \"…\": \"…\" }\n  ],\n  \"page\": {\n    \"next_page_token\": \"eyJvIjoxMDAsImQiOiIyMDI2LTA1LTE0In0\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The array key matches the resource being listed (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accounts"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactions"]},", …). The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page.next_page_token"]}," field is either:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A string - pass it as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page_token"]}," on the next request to fetch the following page."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," - you have reached the last page; there is nothing more to fetch."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"walking-through-every-page","__idx":3},"children":["Walking through every page"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The canonical iteration pattern is a loop that stops when the cursor goes null. In Python:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import os\nimport requests\n\ndef list_all_transactions(account_id: str):\n    token = os.environ[\"RHO_API_TOKEN\"]\n    page_token = None\n    while True:\n        params = {\"account_id\": account_id, \"page_size\": 100}\n        if page_token is not None:\n            params[\"page_token\"] = page_token\n\n        resp = requests.get(\n            \"https://rhoapi.rho.co/api/v1/transactions\",\n            params=params,\n            headers={\"Authorization\": f\"Bearer {token}\"},\n            timeout=30,\n        )\n        resp.raise_for_status()\n        body = resp.json()\n\n        yield from body[\"transactions\"]\n\n        page_token = body[\"page\"][\"next_page_token\"]\n        if page_token is None:\n            return\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Equivalent with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["curl"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"# First page\ncurl \"https://rhoapi.rho.co/api/v1/transactions?page_size=100\" \\\n  -H \"Authorization: Bearer $RHO_API_TOKEN\"\n\n# Subsequent page - pass the next_page_token from the previous response\ncurl \"https://rhoapi.rho.co/api/v1/transactions?page_size=100&page_token=eyJvIjoxMDAsImQiOiIyMDI2LTA1LTE0In0\" \\\n  -H \"Authorization: Bearer $RHO_API_TOKEN\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"common-mistakes","__idx":4},"children":["Common mistakes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Modifying filters between pages."]}," A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page_token"]}," is bound to the query it was issued for. Change ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["account_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sort_by"]},", etc., and you must start over from the first page."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Storing cursors long-term."]}," Cursors are designed for live iteration, not for bookmarks. Their format and lifetime are not part of the API contract and may change without notice."]}]}]},"headings":[{"value":"Pagination","id":"pagination","depth":1},{"value":"Request parameters","id":"request-parameters","depth":2},{"value":"Response shape","id":"response-shape","depth":2},{"value":"Walking through every page","id":"walking-through-every-page","depth":2},{"value":"Common mistakes","id":"common-mistakes","depth":2}],"frontmatter":{"seo":{"title":"Pagination"}},"lastModified":"2026-07-07T16:51:08.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/v1/pagination","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}