---
title: JSON output
description: JSON-by-default output on stdout, a stable error envelope on stderr, and meaningful exit codes for scripting - pipe straight to jq.
---

Every command emits one JSON line on success (except `download --stdout`, which writes the raw bytes). Errors go to `stderr` with a stable `{ error: { code, message } }` envelope, never mixed with the success channel — so a JSON parser downstream sees either a clean record or nothing.

```bash lineNumbers
# JSON output is the default — pipe straight to jq.
$ files --provider fs --root /tmp/store head reports/q1.pdf
{"contentType":"application/pdf","etag":"\"9feb94ca37e5d155\"","key":"reports/q1.pdf","lastModified":1778881504647,"size":48213}

# Errors go to stderr with a stable error code. Exit codes:
#   0  ok
#   1  NotFound (or exists → false)
#   2  a usage error: Invalid, Unsupported, ReadOnly, an unknown flag, a missing option
#   3  Unauthorized
#   4  Conflict
#   5  Provider: the backend or transport failed (safe to retry)
$ files --provider fs --root /tmp/store head nope.txt
{"error":{"code":"NotFound","message":"ENOENT: no such file or directory, lstat '/tmp/store/nope.txt'"}}
$ echo $?
1
```

Use `--pretty` for indented JSON when reading manually. `--no-json` pretty-prints results and prints errors as plain text (`error (NotFound): …`) instead of the JSON envelope; exit codes are unchanged.
