Output and exit codes
What a person reads and what a script reads come out of the same command. This page is the contract between them.
Formats
--format human (the default), --format json, --format csv. All three carry the same content: a command never reaches for JSON directly, so asking for CSV cannot silently return JSON.
Two things sit outside the payload deliberately. A failure is always a JSON envelope in a machine format, because an error is not tabular. And facts about how to read the numbers, the period the server resolved, that a window overlaps imported data, that more rows exist, go to stderr in every format, so a pipeline stays clean:
statable top pages --format csv > pages.csv # stdout is only the table
statable stats --json | jq '.visitors'
Numbers are numbers in JSON, not strings, so jq '.visitors + 1' works. Geographic breakdowns answer twice: a person sees United States, a script gets US, because the code is exactly what the matching filter accepts.
Exit codes
The exit code is the answer, so a script does not have to parse anything.
| Code | Meaning |
|---|---|
0 | Success |
1 | Action required; next_steps names the fix |
2 | The operation failed |
3 | statable check ran and the metric was outside its bounds |
64 | The command line itself was malformed. Nothing was sent |
130 | Interrupted |
64 covers every mistake caught before a request exists: an unknown metric, a filter with no operator, a range that is not a range. Repeating the command unchanged will fail identically, which is exactly what 2 must not be confused with.
Errors
Failures carry a stable code. Prose may be reworded at any time; codes may not. See Errors for the full list.
{
"status": "action_required",
"error": "no API key is configured",
"issues": [{"code": "NOT_AUTHENTICATED", "message": "no API key is configured"}],
"next_steps": ["statable auth login"]
}
On a 429 the CLI reads X-RateLimit-Reset and tells you when to try again rather than guessing. See Rate limits.
In CI
Exit 3 means the number was outside its bounds; 1 and 2 mean the check could not run at all. That separation is the point: a pipeline can tell "traffic dropped" from "the tool is broken".
A rate can be null when it is undefined for the window. check refuses to judge that rather than treating it as zero.
Set the key in the environment, never with --key, and the run leaves nothing behind:
Ready to take control of your web analytics? Try Statable free for 30 days. No credit card required, full feature access, built for GDPR. Start your free trial or view a live demo.