Agents & automation
Output and automation
Use compact text, JSON, JSONL, strict request files, request IDs, timeouts, and stable exit classes in scripts and agents.
Compact text is the default
icloud account list
icloud mail messages list
icloud mail search invoice
Redirecting output does not silently change formats. This keeps ordinary terminal use and agent use predictable.
JSON is explicit
icloud account list --json
icloud mail search invoice --json
A successful response uses a stable envelope with ok, data, and meta. Errors use an error envelope on stderr.
Use a request ID when correlating a larger workflow:
icloud --request-id job-42 mail search invoice --json
JSONL is for streams and per-item work
Long-running watch:
icloud mail watch --jsonl
Bounded multi-item action:
icloud mail move msg_… msg_… \
--from inbox \
--to Projects \
--idempotency-key move-batch-01 \
--yes \
--jsonl
JSONL emits typed item/lifecycle events and a final completion event so a caller can process progress without waiting for one large JSON document.
Put complex requests in JSON
For a search:
{
"query": "invoice",
"folder": "inbox",
"from": "billing@example.com",
"unread": true,
"limit": 20
}
icloud mail search --input-json search.json --json
For a send:
{
"to": ["client@example.com"],
"subject": "Project update",
"body_file": "message.txt",
"idempotency_key": "project-update-07"
}
icloud mail send --input-json request.json --dry-run --json
icloud mail send --input-json request.json --yes --json
Do not mix equivalent positional/request flags with --input-json. Keep process controls such as --yes, --dry-run, global --account, and output selection outside the JSON request.
Discover schemas from the installed build
icloud capabilities --json
The automation section lists commands that accept structured input and links each one to its versioned request/response schema. Use this rather than copying an old request shape into a long-lived integration.
Keep message content opt-in
Structured output does not imply full message content:
icloud mail message show msg_… --json
Ask for content explicitly:
icloud mail message show msg_… --full --json
icloud mail message show msg_… --format html --json
Exact raw MIME is a separate explicit mode. Attachment bytes require an explicit output destination.
Global controls
These work across the command tree where applicable:
--account <selector> choose an account
--home <path> choose a local data root
--timeout <duration> bound normal command work
--no-input never prompt implicitly
--request-id <id> correlate structured output
For mail watch, --timeout applies to each provider/sync attempt rather than ending the foreground watcher itself.
Errors go to stderr
Compact example:
error
code=safety
message="account removal requires --yes"
JSON example:
{"ok":false,"error":{"code":"safety","message":"account removal requires --yes","retryable":false},"meta":{"request_id":"job-42"}}
A failed command does not emit a normal success payload to stdout.
Exit classes
| Exit | Class | Meaning |
|---|---|---|
0 |
success | The command completed. |
1 |
internal | An unexpected CLI failure occurred. |
2 |
usage | Arguments, flags, or request shape were invalid. |
3 |
configuration | Required local configuration or state is unavailable. |
4 |
authentication | A credential is missing or was rejected. |
5 |
unavailable | Connectivity, TLS, provider availability, or timeout prevented the operation. |
6 |
conflict | Existing state makes the requested action ambiguous or conflicting. |
7 |
not found | The requested local object does not exist. |
8 |
safety | Explicit review, input, or authorization is required. |
Branch on these classes or the JSON error.code; do not parse human error prose.
Partial work is reported
Multi-item provider operations cannot pretend to be transactional when earlier items have already succeeded remotely. Structured completion output therefore reports attempted/succeeded/failed counts and whether work was partial.
The default bulk mode stops on the first item failure after request validation. Where supported, use:
--mode continue-on-error
when remaining independent items should still be attempted.
Secrets stay outside ordinary request JSON
Account setup supports explicit secret sources such as --password-stdin, --credential-env, and --credential-file. There is no plaintext --password flag, and credential request JSON does not accept a password value.
See Agent guide for operating conventions and Automation recipes for complete examples.