Free & open source

One CLI for every Zoho service

zone is the unified command line for the Zoho suite — 64 services, 9,432 typed commands, one OAuth login.

Every Zoho service ships its own API, its own scopes, and its own quirks — so anyone automating Zoho ends up writing the same OAuth dance, the same pagination loop, and the same retry logic over and over. zone does that once. You authenticate once, then drive CRM, Books, Desk, People, Projects and 59 more services from a single tool with one consistent output contract.

Install and sign in
npm install -g wanas-zone-cli
zone login

Node.js and an npm registry are all you need. Published by Wanas Apps FZ-LLC — a Zoho Premium Partner.

64 Zoho services
9,432 Typed commands
~7,550 REST endpoints
30 Services at 100% documented coverage

One consent. No token juggling.

Authentication is the part everyone rewrites and nobody enjoys. zone treats it as solved infrastructure.

One OAuth consent

A single browser consent covers every service you pick at login. No per-service client registration, no copying refresh tokens between scripts.

Tokens stay on your machine

Sessions are written to a local store, one file per service. Refresh and 401-retry happen automatically, so a long-running script never dies on an expired token.

Per-project identities

zone login writes a ./.zone store and finds it the way git finds .git — walking up from the working directory. Each project folder can therefore hold a different Zoho identity: a client org here, a sandbox there. --global falls back to ~/.zone.

Datacenter-aware from the start

The datacenter is chosen at login and baked into every base URL, so a UAE org and an EU org never get crossed.

Two ways to drive it

Typed commands for the surface that is already wrapped; a universal proxy for everything else. Both share the same auth, the same output contract, and the same exit codes.

Typed commands

A real command for each operation — request bodies, pagination, file downloads and Zoho’s per-endpoint quirks are handled for you. Every group is discoverable with --help.

zone crm record list Deals --fields Deal_Name,Stage,Amount
zone crm field list Deals
zone books invoice list --status overdue
zone desk ticket list --json

The zone api proxy

Anything not yet typed is still one command away. The proxy signs the request with the same session, resolves the datacenter base URL, and returns the raw body — so a brand-new Zoho endpoint never blocks you.

zone api crm GET /crm/v8/settings/modules
zone api books POST /invoices --data @invoice.json
zone api desk GET /api/v1/tickets --json
For AI engineers

Built for AI coding agents

Ask a coding agent to "pull our overdue invoices and match them to CRM deals" and, without tooling, it will do three things badly: hand-roll an OAuth flow it cannot complete, guess REST paths from memory, and invent field API names that do not exist in your org. Every one of those failures is silent — you get plausible code that returns nothing. zone replaces all three guesses with one authenticated, typed, self-documenting command surface.

Why it changes the outcome

Auth is already done

A human runs zone login once. The agent never sees a secret, never writes an OAuth handler, and never asks you to paste a token into a chat window.

Field names come from your org

zone crm field list Deals returns the real API names from your CRM. The agent reads them instead of hallucinating Deal_Name vs dealName — the single most common cause of a Zoho script that runs cleanly and does nothing.

Output it can actually parse

--json and --toon put machine-readable data on stdout and keep progress messages on stderr, so nothing has to be scraped out of prose. TOON is the more compact of the two when context budget matters.

Failures it can detect

Exit codes mean something: 0 ok, 2 usage, 3 not authenticated, 4 missing scope, 5 Zoho rejected it, 6 blocked by policy, 7 retryable (network, 429, 5xx). With --json the last stderr line is always a structured error object — even for a missing argument — with a hint naming the fix. An agent branches on that instead of retrying blindly.

Discoverable, so it explores instead of guessing

zone <service> --help lists the command groups; zone <svc> <group> --help lists the leaves. An agent that does not know a command can find it in one call rather than inventing one.

The whole guide, on demand

zone llm prints a complete usage guide generated from the live command specs, so it can never drift from what actually ships. zone llm <service> narrows it to one service when the context window is tight.

Install the guide where your agent already looks

zone skill installs a router plus one skill per service — the real command names, the flags Zoho requires, payload shapes and live-org traps — as native skill or rules files for your agent. Only each skill’s one-line description is resident per prompt; the body loads when it triggers. Re-running after an upgrade refreshes zone’s own files and never touches text you wrote.

zone skill --ide claude
Supported targets
  • Claude Code — .claude/skills/zoho-zone/SKILL.md
  • Antigravity / Gemini agent — .agents/skills/zoho-zone/SKILL.md
  • Cursor — .cursor/rules/zoho-zone.mdc
  • Windsurf — .windsurfrules
  • GitHub Copilot — .github/copilot-instructions.md
  • Cline / Roo Code — .clinerules
  • Gemini CLI — GEMINI.md
  • Codex / AGENTS.md standard — AGENTS.md
  • Plain Markdown — ZOHO_ZONE_AI_CONTEXT.md

A realistic agent workflow

The task: find every Closed Won deal in CRM with no matching paid invoice in Books. Here is what the agent actually runs.

  1. 01

    A human authenticates the project, once

    The browser consent is the one step that needs a person. Run in the project folder, it writes ./.zone, so this identity applies to this repository only.

    zone login crm books
  2. 02

    The agent loads the command surface

    One command puts every typed command group into the agent’s rules file. From here it selects commands rather than inventing them.

    zone skill --ide claude
  3. 03

    It reads your real schema before writing a query

    The field list comes from your org, so the filter it builds next uses API names that exist.

    zone crm field list Deals --json
  4. 04

    It pulls both sides with one identity

    Same session, two services, no second OAuth flow. Pagination is handled by the command.

    zone crm record list Deals --fields Deal_Name,Stage,Amount --per-page 200 --json
    zone books invoice list --status paid --json
  5. 05

    It handles failure instead of hiding it

    If Books was never consented, the command exits 3 and prints a structured error. The agent stops and asks you to run login for that one service — rather than retrying a call that can never succeed.

    # exit 3 — not authenticated
    {"ok":false,"error":{"code":"NOT_AUTHENTICATED","message":"Not signed in to books.","hint":"Run \"zone login books\" (or \"zone login --all\").","http_status":null,"zoho":null,"context":null}}

Write operations run only when they are explicitly invoked. Nothing above mutates a record, and an agent cannot acquire a scope you did not consent to.

Safe to hand to an agent pointed at a live org

A coding harness that grants shell access to zone has granted every write to every authenticated Zoho service — it cannot express “reads only”. So the guardrails live inside zone, at the one seam every request passes through, and a test fails if any call ever walks around it.

--dry-run on every command

A write is resolved and printed — method, path, body — instead of sent, exit 0. Reads still run, so an agent can leave it on while it builds a call. Uploads, downloads and zone bug honour it too.

zone crm record delete Leads 123 --dry-run --json
{"dry_run":true,"service":"crm","method":"DELETE","path":"/Leads/123","query":{},"body":null,"api_version":null}

A read-only policy that means read-only

ZONE_POLICY (or --allow / --deny) gates by service and method; deny always wins and a blocked call exits 6 naming the rule. Endpoints are classified by what they do, not their verb — COQL and bulk read count as reads, and the Campaigns writes Zoho serves over GET count as writes.

ZONE_POLICY='*:GET' zone crm record create Leads --data @lead.json --json
{"ok":false,"error":{"code":"POLICY_DENIED","message":"Blocked by policy: crm:POST /Leads — not in the allow list.", ...}}

Secrets never leave in the clear

Fields named like credentials are masked on every path out — stdout, --verbose details and the machine error line alike — and the literal value of any ZONE_* secret is scrubbed from free text. Tokens are only ever attached to Zoho hosts, and a path with “..” is refused before the policy runs.

zone books org list --json | grep -c "«redacted»"

An audit log you can hand to a client

--audit <file> appends one JSONL line per request — real, denied or dry-run — with method, path, effect (read or write), status and timing. Metadata only, never a body, so the log cannot become a new place client data leaks.

{"ts":"2026-09-04T16:35:54.367Z","service":"crm","method":"DELETE","path":"/Leads/1","effect":"write","status":null,"outcome":"denied","policy":"denied","dry_run":false,"ms":null,"pid":40992}

All four are enforced at one seam — zone’s own API client — through which every typed command, the zone api proxy, every file upload and download, and zone bug pass. The suite fails if a raw HTTP call appears anywhere outside it.

Coverage, measured against Zoho’s own docs

Every service was checked against its official API documentation and the gap closed. 30 of the 64 sit at 100% of their documented surface; across the suite that is roughly 7,280 documented operations. Where Zoho publishes a machine-readable spec, the commands are generated from it rather than from prose.

ServiceCommandsWhat that covers
Zoho Desk931Tickets, knowledge base, community, assignment rules, gamification
Zoho Books903Generated from Zoho’s own OpenAPI specs, alongside Invoice, Billing and Expense
Zoho CRM792V8/V9 metadata end-to-end — customization, process automation, security, Zia — plus COQL, bulk jobs and the Deluge toolchain
Zoho Inventory556Items, warehouses, orders, shipments, the full stock lifecycle
Zoho Projects507The complete V3 surface, including the v3.1 endpoints
Zoho People447Both published versions: v1/v2 for LMS and timesheets, v3 for leave and shifts

Deluge, from your editor

Push, pull and test Deluge functions as files. Compilation errors come back with real line numbers that match the file on disk, not a blank 400.

Full CRM metadata extraction

zone crm extract pulls your org’s modules, fields, layouts and functions to disk — the authoritative reference for writing Deluge or REST code against that org, and a natural input for an AI agent.

Every datacenter, including the regional exceptions

The datacenter is part of the login, not an afterthought — and zone knows which products actually exist in each one.

  • com
  • eu
  • in
  • com.au
  • jp
  • uk
  • ca
  • sa
  • ae
  • cn

Regional products are enforced at login rather than failing later: Zoho Payroll, for example, exists only in com, in, ae and sa, so zone rejects a Payroll login on any other datacenter up front. Requesting a regional scope on the wrong datacenter would otherwise void the entire consent.

Need this wired into your own Zoho stack?

We are a Zoho Premium Partner with 300+ implementations behind us. If you want custom integrations, Deluge automation, or AI agents working against your Zoho org, we can help.