Output formats
Render records as a table, JSON, CSV, or your own template, and script against the exit codes.
Every command that emits records renders through the same formatter. Pick a
format with --format (or -f), or let goodread choose: a table when writing to
a terminal, JSONL when piped.
Formats
goodread search dune -f table # aligned columns for reading
goodread search dune -f jsonl # one JSON object per line, for piping
goodread search dune -f json # a single JSON array
goodread search dune -f csv # spreadsheet friendly
goodread search dune -f tsv # tab-separated
goodread search dune -f url # just the Goodreads URL of each row
goodread search dune -f raw # the underlying bytes, unformatted
| Format | Best for |
|---|---|
table |
Reading on a terminal |
jsonl |
Piping into another tool, one object at a time |
json |
Loading a whole result as an array |
csv / tsv |
Spreadsheets and quick column math |
url |
Feeding URLs into other commands |
raw |
The unformatted bytes |
Narrowing columns
Keep only the fields you want:
goodread book 2767052 --fields title,avg_rating,ratings_count
goodread shelf 1 --shelf read --fields title,author_name,rating
--no-header drops the header row in table and csv output, which is handy
when a downstream tool expects bare rows.
Templating rows
For full control over each line, apply a Go text/template. The fields are the record's keys:
goodread book 2767052 --template '{{.title}} by {{.author_name}} ({{.avg_rating}})'
goodread shelf 1 --shelf read --template '{{.title}} {{.rating}}'
Piping
Because the default adapts to the destination, the same command reads well by hand and parses cleanly in a pipe:
goodread shelf 1 --shelf read # a table, because this is a terminal
goodread shelf 1 --shelf read | jq -r .title # JSONL, because this is a pipe
--limit (or -n) caps the number of rows; 0 means all.
Exit codes for scripting
goodread returns a stable exit code so a script can branch on the outcome:
| Code | Meaning |
|---|---|
0 |
OK |
1 |
Error |
2 |
Usage error |
3 |
No data (nothing matched) |
4 |
Partial (some items failed) |
5 |
Blocked (a WAF challenge) |
For example, treat a challenge differently from a real failure:
goodread book 2767052 --format json > book.json
case $? in
0) echo "got it" ;;
5) echo "blocked, retry with --cookies" ;;
*) echo "failed" ;;
esac
See troubleshooting for what to do about exit 5 and exit 3.