Paging Through Audience Record IDs with the Clay CLI
?q={your_question}.Paging Through Audience Record IDs with the Clay CLI
Walk a saved audience's full record set page by page, using Clay's real audiences records search-ids, sized correctly with a page-size heuristic straight from the command's own guidance rather than a guessed default.
What you will build
A cursor-paginated walk over a segment's record ids, sized using the command's own documented rule of thumb.
clay audiences records search-count --audience-id <id> --entity-type <type> (size the scope first)
↓
clay audiences records search-ids --audience-id <id> --entity-type <type> --limit <sized>
↓
clay audiences records search-ids ... --cursor <cursor-from-previous-page>
↓
... until no "cursor" key is present
AI Prompt
Using the Clay CLI, page through every record id in a saved audience. Requirements: - `clay audiences records search-ids [--query <dsl> | --audience-id <id> | --filter <ast>] --entity-type <people|companies|deals> [--limit <n>] [--cursor <cursor>] [--archived]`. --entity-type is required even when --audience-id is set (it is not inferred from the audience), the same rule as search-count. - --query, --audience-id, and --filter are mutually exclusive scope selectors; passing none searches every record of the entity type. - Size --limit from `search-count` before paging. The command's own guidance is roughly limit = count/10 (targeting ~10 calls total), clamped to a page size between 100 and 2000, and only going above 2000 for scopes past 20k records. Both extremes have a cost: tiny pages exhaust the workspace's shared per-minute rate budget fast, while oversized pages make each call slow. - "cursor" is present in the response only when more pages remain, so loop on `jq -e '.cursor'` rather than counting pages. - With --query, the DSL root verb for this command is "select from <people|companies|opportunities>", not "count from" (that verb is only for search-count). - Run the verification step below before finishing.
Prerequisites
- The
clayCLI on PATH, authenticated viaclay login(an OAuth session, not a Public API key) jq
Note: JSON samples below are trimmed to the fields relevant to each step. Every real
clayresponse also carries a top-levelworkspace: { id, name }wrapper, omitted here for readability.
1. Size the scope first
clay audiences records search-count --audience-id audseg_0tl84p1ZQ8RRShHSAdX --entity-type companies
Real output against this workspace's test segment:
{"count": 0}
2. Page with a sized limit
clay audiences records search-ids --audience-id audseg_0tl84p1ZQ8RRShHSAdX --entity-type companies --limit 100
Real output. No records yet exist in this workspace, and no cursor key is present since nothing remains to page:
{"data": []}
3. Loop until no cursor remains
CURSOR=""
while :; do
page=$(clay audiences records search-ids --audience-id audseg_0tl84p1ZQ8RRShHSAdX --entity-type companies --limit 100 ${CURSOR:+--cursor "$CURSOR"})
echo "$page" | jq -r '.data[]'
CURSOR=$(echo "$page" | jq -r '.cursor // empty')
[ -z "$CURSOR" ] && break
done
4. Use the DSL's select from form instead of a saved audience
clay audiences records search-ids --query 'select from companies where industry contains "Software"'
Real output, the same empty result:
{"data": []}
Verify the result
Confirm the behavior above holds by re-running the key command and checking the result:
clay audiences records search-ids --audience-id audseg_0tl84p1ZQ8RRShHSAdX --entity-type companies --limit 100
Expected: --entity-type is required alongside --audience-id; the response omits cursor entirely once no further pages remain, so a jq -e '.cursor' loop terminates cleanly rather than needing a page-count guess.
How it works
The command's own page-sizing guidance (limit = count/10, clamped 100-2000) reflects two competing costs: the workspace's rate budget is shared and charged per call regardless of page size, so tiny pages on a large scope exhaust it fast, while very large pages make each individual call slower and more likely to time out. Checking search-count first informs that sizing decision instead of leaving it to a guess.
Common issues
Guessing a page count instead of checking for cursor
It is possible to assume the response always includes a cursor field, just empty or null when done. In practice, cursor is omitted from the response entirely once nothing remains, rather than set to null or an empty string. Use jq -e '.cursor' (which fails and exits 1 on a missing key) as the loop condition.
Using count from with search-ids
search-count and search-ids share almost identical flags, which can suggest they share DSL syntax too. In practice, search-ids (and records get) use select from <root>; only search-count uses count from <root>. Mixing them up produces a validation_error naming the expected verb.
Next steps
- Feed paged ids into
clay audiences records get --ids <comma-separated, max 100>to bulk-fetch field values. - Re-check
search-countperiodically during a long page-through if the underlying data may be changing, since the total can shift mid-walk.
verification: status: verified tested_at: "2026-09-21" product_version: "clay CLI 1.2.0" command: "clay audiences records search-ids --audience-id audseg_0tl84p1ZQ8RRShHSAdX --entity-type companies --limit 100" expected_result: "A real data array (empty in this workspace) is returned with no cursor key present, confirming a jq -e '.cursor' loop terminates correctly rather than needing a guessed page count."