{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Pagination"},"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 Titan Public API support ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["two pagination modes"]},":"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cursor (keyset) pagination"]}," — opaque cursor pointing at the next page. Stable across concurrent updates."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Offset pagination"]}," — classic ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}," + ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]},". Simple but can skip or duplicate rows when the underlying set changes between requests."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cursor is the recommended mode for anything scanning more than a few pages or resuming a paused sync. Offset is fine for small, one-off queries."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"request-parameters","__idx":1},"children":["Request parameters"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every paginated endpoint accepts:"]},{"$$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":"Default"},"children":["Default"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["integer"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["server default"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Maximum rows returned per page."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["integer"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Zero-based offset. ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Ignored when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]}," is set."]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["(unset)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Opaque cursor. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"\""]}," = request the first cursor-based page. Omit entirely to use offset mode."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"which-mode-youre-in","__idx":2},"children":["Which mode you're in"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]}," unset"]}," → offset mode. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}," + ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," drive paging."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]}," present"]}," (including empty string ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"\""]},") → cursor mode. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," is ignored; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}," still caps page size."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"response-envelope","__idx":3},"children":["Response envelope"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"observations\": [ ],\n  \"next_cursor\": \"eyJvZmZzZXQiOjEwMCwic25hcHNob3QiOiIyMDI2LTA3LTAxIn0=\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The primary result field contains the current page."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["next_cursor"]}," — pass as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor"]}," on the next call. When ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["absent or empty"]},", you have reached the end."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The cursor is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["opaque"]}," — treat it as a bag of bytes. Do not decode, mutate, or persist parts of it."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"iterating-with-cursor-pagination-recommended","__idx":4},"children":["Iterating with cursor pagination (recommended)"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"CURSOR=\"\"\nwhile :; do\n  RESP=$(curl -sX POST \"https://titanapi.securityscorecard.io/public/v1/observations\" \\\n    -H \"Authorization: Bearer $TITAN_API_TOKEN\" \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"limit\\\": 100, \\\"cursor\\\": \\\"$CURSOR\\\"}\")\n\n  echo \"$RESP\" | jq '.observations[]'\n\n  CURSOR=$(echo \"$RESP\" | jq -r '.next_cursor // \"\"')\n  [ -z \"$CURSOR\" ] && break\ndone\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"iterating-with-offset-pagination","__idx":5},"children":["Iterating with offset pagination"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"OFFSET=0\nLIMIT=100\nwhile :; do\n  RESP=$(curl -sX POST \"https://titanapi.securityscorecard.io/public/v1/observations\" \\\n    -H \"Authorization: Bearer $TITAN_API_TOKEN\" \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"limit\\\": $LIMIT, \\\"offset\\\": $OFFSET}\")\n\n  COUNT=$(echo \"$RESP\" | jq '.observations | length')\n  [ \"$COUNT\" -eq 0 ] && break\n\n  echo \"$RESP\" | jq '.observations[]'\n  OFFSET=$((OFFSET + LIMIT))\ndone\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"guidance","__idx":6},"children":["Guidance"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Prefer cursor for anything non-trivial."]}," Cursor is stable across updates; offset can silently skip or duplicate rows when observations arrive mid-scan."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Do not decode the cursor."]}," It's opaque — do not persist parts of it, mutate it, or compare cursors for ordering."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Do not persist cursors across long gaps."]}," Cursors typically expire after 24 hours. Restart from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cursor=\"\""]}," and dedupe by resource id."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Do not parallelise a single stream."]}," Give each worker its own disjoint filter (e.g. by time range) instead of splitting one cursor across workers."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Stop on empty ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["next_cursor"]}," (cursor mode) or empty results (offset mode)."]}," A short page in cursor mode is not necessarily the last page — always check ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["next_cursor"]},"."]}]}]},"headings":[{"value":"Pagination","id":"pagination","depth":1},{"value":"Request parameters","id":"request-parameters","depth":2},{"value":"Which mode you're in","id":"which-mode-youre-in","depth":3},{"value":"Response envelope","id":"response-envelope","depth":2},{"value":"Iterating with cursor pagination (recommended)","id":"iterating-with-cursor-pagination-recommended","depth":2},{"value":"Iterating with offset pagination","id":"iterating-with-offset-pagination","depth":2},{"value":"Guidance","id":"guidance","depth":2}],"frontmatter":{"seo":{"title":"Pagination"}},"lastModified":"2026-08-19T12:45:50.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/guides/pagination","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}