Skip to content

jq expressions

Every getstream api call accepts --jq <expression>. The expression runs on the parsed response in-process, before anything is printed. There is no separate jq binary to install and no pipe to quote around.

getstream api QueryChannels --request '{"limit":30}' --jq '.channels | length'

The expression language is jq; anything the manual describes works here. This page documents the behaviors specific to the CLI and the expressions that come up most with Stream responses.

Result encoding

  • String results print JSON-encoded, with quotes. Strip them with tr -d '"' before feeding values into read or xargs.
  • Object and array results print as formatted JSON.
  • @csv and @tsv return each row as a single JSON string, so a row prints wrapped in quotes with its inner quotes escaped. Unwrap it with jq -r ..
  • Results are never truncated. A raw response shortens long arrays when stdin is not a terminal or NONINTERACTIVE is set; a --jq result always prints in full.

Common expressions

Count the items in a page:

--jq '.channels | length'

Emit one field per line:

--jq '.channels[].channel.cid'

Project selected fields from each item:

--jq '.channels[].channel | { cid, member_count }'

Filter items by a field the query cannot select on:

--jq '.users[] | select(.online) | .id'

Rank within a page and take the top item:

--jq '[.channels[].channel] | sort_by(.member_count) | reverse | .[0].cid'

Group and count:

--jq '[.flags[]] | group_by(.user.id) | map({ user: .[0].user.id, flags: length })'

Default a missing or null field with //:

--jq '.channels[].channel | { cid, name: (.name // "(unnamed)") }'

Format a row as CSV:

--jq '.channels[].channel | [.cid, .member_count] | @csv'

Query* endpoints page their results (QueryChannels at 30 per page), so length, sort_by and group_by operate on a single page. Narrow the set server-side with filter_conditions and sort, or advance with offset or the next cursor.

See also