### Zoho Cliq — three different id spaces, no context to set, and every post lands in front of a whole team instantly

Three things cause most failures here: a channel is addressed by **three different keys depending on the command** (unique name, channel id, chat id) and picking the wrong one 404s, **posting a message uses the Webhooks scope rather than the Messages scope**, and there is no draft state — a post is live in a team channel the moment the call returns.

#### No context id — but you still have to know which key a command wants

Cliq has no org or portal ctx: after `zone login cliq`, `zone cliq channel list` works. What replaces it is a per-command id, and the three families are not interchangeable.

| Key | Where it appears | Commands |
|---|---|---|
| channel **unique name** | `/channelsbyname/<name>/…` | `zone cliq message tochannel <channelName>`, `zone cliq file channel <channelName>` |
| **channel id** | `/channels/<id>/…` | `zone cliq channel get`, `channel members`, `channel addmembers`, `zone cliq message tochannelid <channelId>`, `zone cliq thread list <channelId>` |
| **chat id** | `/chats/<id>/…` | every message **read** or edit: `zone cliq message list <chatId>`, `message get`, `message edit`, `message delete`, `message react`; also `zone cliq chat pinned`, `chat members`, `zone cliq scheduled-message create <chatId>` |
| **user id** — email or ZUID | `/buddies/<id>/…`, `/users/<id>` | `zone cliq buddy message <userId>`, `zone cliq file user <userId>`, `zone cliq user get` |
| bot **unique name** | `/bots/<name>/…` | `zone cliq bot message <botName>`, `bot subscribers`, `bot associate` |

The sharpest edge: **there is no `/channels/<id>/messages`**. Reading a channel's history goes through the chat surface, so you need the channel's *chat* id — a third value, distinct from both the channel id and the unique name. Get the channel record with `zone cliq channel get <channelId>` and take the chat id from it (the field is documented as `chat_id`; not verified live here). `zone cliq channel list` is where all of a channel's keys come from at once, and `--level organization|team|external` plus `--joined` narrow it.

`zone cliq chat list` is your **direct** chats only — it is not a list of channels.

#### Writing a message

```bash
zone cliq message tochannel <channelName> --data '{"text":"Deploy finished"}'
zone cliq message tochannelid <channelId>  --data '{"text":"Deploy finished"}'
zone cliq buddy message <userId>           --data '{"text":"Deploy finished"}'
zone cliq message tochat <chatId>          --data '{"text":"…"}'          # also how you reply into a thread
zone cliq bot message <botName>            --data '{"text":"…"}'
zone cliq message tochannel <channelName> --bot-unique-name <bot> --data '{"text":"…"}'   # post AS a bot
```

The only body field the specs prove is **`text`**. Cliq's message format also supports rich content — *from Zoho's documentation, not verified here* — as sibling keys on the same object: `card` (`{"title":…,"theme":"modern-inline"}`), `slides` (an array of `{"type":"table|text|images|list","title":…,"data":…}`) and `buttons` (an array of `{"label":…,"action":{"type":"invoke.function|open.url","data":{…}}}`). Treat those shapes as a starting point and check one against a scratch channel before using them in client work.

**Posting is `ZohoCliq.Webhooks.CREATE`, not `Messages.CREATE`.** Every "post a message" and "share a file" endpoint quotes that scope. If consent was granted without it, reads succeed and every write fails — which reads like a bug rather than a permission problem. `Messages.{READ,UPDATE,DELETE}` cover listing, editing, deleting and reactions.

#### Visibility, and how little undo there is

`message tochannel` and `tochannelid` publish into a team or organization channel: every member sees it immediately, with a notification. There is no draft, no preview and no scheduled-send on those two — scheduling exists only for chats (`zone cliq scheduled-message create <chatId> --data '{"text":"…","schedule_time":…,"schedule_timezone":"Asia/Dubai"}'`). The only retraction is `zone cliq message delete <chatId> <messageId>`, which needs a **chat id and a message id you must already have captured** — there is no delete-by-channel-name. Before posting anything client-visible, decide how you would take it back.

`zone cliq buddy message` is a 1:1 DM and is the safe target for testing.

#### Files are multipart and go through a handler

```bash
zone cliq file channel <channelName> -f ./report.pdf --data '{"text":"Q4 numbers"}'
zone cliq file chat <chatId> -f ./a.png -f ./b.png
zone cliq file get <fileId> --out ./downloaded.pdf
```

`-f/--file` is repeatable, **max 10 files, 50 MB each**, and these are the only Cliq commands that are not plain REST. Same Webhooks.CREATE scope as posting; downloading is `ZohoCliq.Attachments.READ`.

#### Paging, time and a few naming traps

- Most lists take `-l, --limit <n>`; several also take `--next-token <t>` (`zone cliq call history`, `department list`, `designation members`, `thread list`, and all four `export` commands). `zone cliq database list` uses `--from-index` / `--start-token` instead. There is no uniform page number.
- **All times are epoch milliseconds** — `--from-time`, `--to-time`, and `remind_time` / `snooze_time` in reminder bodies.
- `zone cliq designation members` requires `--limit`; `zone cliq event get` requires `--calendar-id`; the four `export` commands require `--fields`.
- **Roles are served from `/profiles`** — `zone cliq role list`, `role permissions`, `role add-users`. Searching for "profile" in the command list finds nothing.
- `zone cliq designation list` is the only designation read; there is no get-by-id despite the doc page title.
- `zone cliq export conversations|channels|members|messages` is a **different API entirely** — the maintenance API on `/company/<companyId>/maintenanceapi/v2`, org-admin scopes only, with the company id as a positional argument.
- `zone cliq remote checkin` and `remote checkout` punch a real attendance clock and need ZohoPeople scopes on top of Cliq's.

#### Errors → what to do

| What you see | Meaning | Do |
|---|---|---|
| 404 posting to a channel you can see | you passed the channel id to `message tochannel`, which wants the unique name | use `message tochannelid`, or take the unique name from `channel list` |
| 404 listing a channel's messages | there is no channel-messages path; you passed a channel id where a chat id belongs | fetch the channel's chat id from `channel get` |
| reads work, every post 401s | consent lacks `ZohoCliq.Webhooks.CREATE` | human re-runs `zone login cliq` and grants it |
| an OAuth consent that is rejected outright | a `.ALL` scope was requested for Channels/Chats/Messages/Users — those only exist as READ/CREATE/UPDATE/DELETE | only Reminders and StorageData have `.ALL` |
| a message posted to the wrong channel | there is no undo except `message delete <chatId> <messageId>` | capture the chat and message ids from the post response |
| "required option" on a list | `--limit`, `--calendar-id` or `--fields` is mandatory there | required flags are marked `*` in this skill's command list |
| 403 on the `export` group | maintenance API, org-admin only | run it as an org admin, or use `message list` per chat |
| exit 3 | not signed in — Cliq is its own consent | human runs `zone login cliq` |
| exit 4 | the token lacks that granular scope | human re-logs in that service |

> Command names, groups, paths, HTTP verbs, required flags, the three id families (the `/channelsbyname/`, `/channels/` and `/chats/` path split), the file-upload limits, and the Webhooks-vs-Messages scope split come from the installed specs, so they are exact. The rich-message keys (`card`, `slides`, `buttons`) and the `chat_id` field name on a channel record follow Zoho's Cliq v2 documentation and were **not** re-verified live — this account has no Cliq session. Run `zone login cliq` and post once to a scratch channel to confirm them.
