difyctl is built to be scripted: data goes to stdout while everything else goes to stderr, the -o global flag selects the output format, and failures exit with a predictable code.
Output Formats
-o <format> selects how a command renders its result on stdout. Each command supports a subset of the five formats, listed in its --help and the Flags table on its reference page.
Without
-o, list commands such as get app print an aligned text table and other commands print text.
The JSON shapes are stable: list commands such as get app print a JSON object with the rows in an array, and two runs of the same command return the same top-level structure. For a command’s exact JSON shape, see its reference page.
Output Channels
The rules worth scripting against:
- On failure, stdout stays empty. You never have to filter error text out of captured data.
- On success,
getanddescribecommands leave stderr empty;run appandresume appmay print hints there. - Progress spinners appear only in a terminal, on stderr, and are suppressed under
-o json,-o yaml, and-o name. - Piped output carries no ANSI color codes.
- If the consumer of a pipe exits early (
difyctl get app -o name | head -2),difyctlexits0rather than failing on the broken pipe.
Errors
Errors go to stderr. In the default human format, an error is acode: message line plus optional detail lines:
request: <METHOD> <url> and http_status: <n> lines follow.
When the server’s reply carries Dify’s standard error body, the header line shows the server’s more specific code (not_found, invalid_param) instead of the CLI’s transport-level code.
Per-field validation details follow as indented lines, and the server’s hint appears when difyctl has none of its own.
Under -o json, the same error becomes a single-line JSON object on stderr:
-o json switches error rendering: -o yaml failures print the human format.
For what each code means and how to fix it, see Troubleshooting.
Exit Codes
One nuance for strict scripts: parser-level mistakes (an unknown command, an unknown flag, a flag missing its value) exit
1 with a plain-text message, while an invalid value for a known flag exits 2.
A Paused Workflow Run Exits 0
A Workflow or Chatflow app can pause mid-run to collect human input. The pause is a successful outcome, not a failure:run app and resume app exit 0 and print a paused payload to stdout.
To detect a pause in a script or an agent, run with -o json and check stdout for "status": "paused"; don’t branch on the exit code.
For the payload shape and the resume protocol, see When a Workflow Pauses on the Apps reference.