Skip to content
Latchkey

curl piped to jq: Parse API JSON in CI

curl -s url | jq -e '.field' fetches an API response and extracts or asserts a field, failing the step when jq's filter yields false or null.

The curl-into-jq pattern is the workhorse of shell-based API checks: curl fetches the JSON, jq queries it, and jq -e turns the queried value into an exit code you can gate on.

What it does

curl fetches the response body and jq parses and queries it. With -e (--exit-status), jq exits 1 if the last output is false or null and 0 otherwise, so a query like .status == "ok" becomes a pass/fail gate. -r prints raw strings without JSON quotes for use in later shell steps.

Common usage

Terminal
# extract a field into a shell variable
id=$(curl -s example.com/api/me | jq -r '.id')
# gate: fail the step unless status is "ok"
curl -s example.com/health | jq -e '.status == "ok"' > /dev/null
# assert an array is non-empty
curl -s example.com/api/items | jq -e '.items | length > 0' > /dev/null

Options

PieceWhat it does
curl -sSilent: no progress meter to pollute the pipe
curl -fFail (exit 22) on HTTP 4xx/5xx before jq runs
jq -eExit 1 when the result is false or null
jq -rRaw output: strings without surrounding quotes
jq -cCompact single-line output

In CI

Add curl -f so an HTTP error fails before jq ever parses an error page, and remember set -o pipefail in bash so a curl failure on the left of the pipe is not masked by a passing jq on the right. Use jq -e whenever the query is meant to be an assertion.

Common errors in CI

jq: error (at <stdin>:0): Cannot index string with "field" or parse error: Invalid numeric literal means jq received HTML or an error page instead of JSON; add curl -f to fail early. jq: error: null (null) has no keys means the path did not exist. A silent pass on a failed request means pipefail is off, so bash only saw jq's exit code.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →