# CLI for agents

Give an agent a read-first CLI workflow with non-interactive credentials, explicit IDs, JSON output, verification, and safe handling of ambiguous writes.

Give agents the same CLI commands people use, with a narrower permission boundary. Discover commands and IDs first, obtain approval for writes, and verify state before retrying.

## First command

Install the [CLI](/cli), then discover capabilities without touching remote state:

```bash
zernio --version
zernio --help
zernio posts:create --help
```

Inject `ZERNIO_API_KEY` through the runner's secret manager. Do not use browser login in an unattended job, store keys in prompts, or ask an agent to invent missing credentials.

## Commands

| Agent task | Discovery or read | Write only after approval | Verify |
|---|---|---|---|
| Prepare a post | `accounts:list`, `accounts:health` | `posts:create --draft` with text and accounts | `posts:get` with returned ID |
| Schedule a draft | `posts:get` | `posts:update` with `--draft=false` and `--scheduledAt` | `posts:get` |
| Reply to a customer | `inbox:conversations`, `inbox:messages --sortOrder desc` | `inbox:send` with account, conversation, and message | `inbox:messages --sortOrder desc` |
| Report performance | `analytics:posts`, `analytics:daily` | None | Check date range and pagination |
| Remove content or revoke access | Inspect the exact resource | Explicit human approval for delete, unpublish, or key revocation | Read state again |

See [posting](/cli/posting), [inbox](/cli/inbox), and [analytics](/cli/analytics) for complete command examples and required arguments. Entries here are an execution plan, not complete invocations.

## Discover IDs before writing

List accounts, inspect the output, and select the account matching the requested profile, platform, and username:

```bash
zernio accounts:list > accounts.json
jq '.accounts[] | {id: (._id // .id), platform, username}' accounts.json
```

Set `ACCOUNT_ID` to that verified ID. Do not select the first account automatically. Profile IDs, connected-account IDs, platform IDs, and ad-account IDs are different identifiers.

## Create and verify a draft

After approval of the exact text and target, run this Bash example with `ACCOUNT_ID` already set:

```bash
: "${ACCOUNT_ID:?Select a verified account ID}"
if zernio posts:create --text "Draft for review" \
  --accounts "$ACCOUNT_ID" --draft > draft.json 2> cli-error.txt; then
  POST_ID=$(jq -er '.post._id // .post.id' draft.json) || exit 1
  zernio posts:get "$POST_ID" --pretty
else
  printf '%s\n' 'Inspect cli-error.txt and remote state before retrying' >&2
fi
```

Confirm the returned content, draft status, and targets. Report the post ID and observed state. Do not claim it was published or schedule it without separate approval.

## Handle failures without duplicates

1. Check the process exit status before parsing stdout. API-handler errors go to stderr; parser errors and login progress can be plain text.
2. For permission or validation failures, correct the identified input or scope. Do not retry the same request unchanged.
3. After a timeout or connection failure during a write, treat the outcome as unknown. The server may already have applied it.
4. Read by the returned resource ID when available. Otherwise, list the relevant posts or messages and match the intended target, content, and time before deciding whether to retry.
5. Inbox messages are oldest-first by default. Use `inbox:messages --sortOrder desc` with the required IDs to check recent sends; follow pagination when the relevant message is outside that page.
6. If state remains ambiguous, stop and report uncertainty. Never blindly repeat creates, sends, launches, deletes, or `posts:retry`.

No global confirmation or dry-run flag protects arbitrary writes. `posts:bulk-upload --dryRun` is command-specific. Draft creation is still a remote write, not a dry run.

## Read as Markdown

Use **Open → View Markdown** on any docs page. The same content is available at `https://docs.zernio.com/llms-mdx/cli/agents` and `https://docs.zernio.com/llms-mdx/cli/posting`.

Start with the relevant task page rather than loading all documentation. Use [the full text export](https://docs.zernio.com/llms-full.txt) only when broader context is necessary.

## How it behaves

- Pin and record the CLI version used by the runner. Check help rather than deriving commands from operation IDs.
- Use JSON output directly; `--pretty` is optional and there is no `--json` switch.
- Keep credentials, customer messages, and API-key creation output out of shared logs.
- Prefer read-only keys for analysis. Require human approval for publication, customer-visible messages, ad spend, deletion, and credential changes.
- A successful API response is evidence to inspect, not a substitute for checking the intended result.

## Related

- [Authentication](/cli/authentication): credential precedence and CI
- [Options and output](/cli/options): exit codes and pagination
- [Posting commands](/cli/posting): create, update, edit, and unpublish
- [Inbox commands](/cli/inbox): read before replying