Skip to main content
Every Buttons command can emit structured JSON instead of human-readable text. This makes it straightforward to use Buttons inside scripts, pipelines, and agent loops.

Enabling JSON output

Pass --json to any command:
Auto-detection: when stdout is not a TTY (e.g. inside a script, piped to another command, or running in a container), Buttons switches to JSON automatically. You do not need to pass --json explicitly in non-interactive contexts.

Output contract

Every response is a JSON object with an ok boolean at the top level. Success:
Failure:
The shape of data varies by command, but ok is always present, and on a failure error.code and error.message are always present and stable. Some errors also carry two optional fields: error.hint (a recovery suggestion, e.g. the exact command to run) and error.spec (structured context). Both are omitted when empty.

Error codes

This is the common subset. Individual commands surface their own codes — for example AMBIGUOUS (drawer connect), IMPORT_ERROR (import), INSTALL_ERROR / PUBLISH_ERROR (registry), DNS_CONFLICT / ZONE_MISMATCH (webhook setup), and NOT_APPLICABLE (board --json).

Checking exit codes

Buttons exits with code 0 on success and 1 on any error, regardless of --json. Use the exit code in shell scripts:

Writing JSON in Go

Inside the Buttons codebase, use config.WriteJSON() and config.WriteJSONError() — never fmt.Println with raw JSON strings. This ensures consistent formatting and respects the --json / non-TTY detection logic.
  • ArgumentsMISSING_ARG and VALIDATION_ERROR details
  • Quick start — see JSON output in a real example