You are operating zoho-inventory-cli — a wrapper over the Zoho Inventory API at https://www.zohoapis.<dc>/inventory/v1.
Zoho publishes no OpenAPI spec and no markdown for Inventory. npm run docs:api
extracts text from the official HTML pages into docs/api/ (17 resources) — a
convenience mirror for grepping offline, not a citable spec. Every file carries its
canonical URL: when a detail matters, open it. If the extraction and the page disagree,
the page wins.
That is weaker than the sibling CLIs, and deliberately labelled so: zoho-desk-cli
renders Zoho's official OAS, amazon-sp-api-cli renders Amazon's official models, and
shopify-admin-cli mirrors Shopify's own markdown. Only here is the local copy derived.
11 CLI resources have no Inventory page — mostly Books-side (credit notes, customer
payments, vendor credits, retainer invoices, taxes), and the Books docs host returns 403
to automated fetches. docs/api/README.md lists them. Diagnose from the docs, not from
the error string.
- Read every file in
knowledge/. Especially:oauth-refresh.md,header-format.md,organization-id.md,pagination.md,india-gst-and-locations.md,sales-order-cycle.md,url-quirks.md. The Zoho API has Indian-tax rules, an opinionated SO cycle, and several inconsistent URL conventions that aren't obvious from--help. - Use
zoho-inventory-cli --help,zoho-inventory-cli <resource> --help,zoho-inventory-cli <resource> <action> --help. Help is generated from the runtime registry, so it never drifts from real behaviour. - Run
zoho-inventory-cli login --status --jsonif a command surprises you withauth_missingorauth_invalid— confirms which source is providing the token and whetherZOHO_INVENTORY_DCmatches the org.
- Command shape:
zoho-inventory-cli <resource> <action> [flags]. Thelogincommand is dispatched separately. - Errors: JSON on stderr with exit code 1. Fields:
type, code, message, retryable, retryAfter?, details?. Codes:auth_missing | auth_invalid | forbidden | not_found | conflict | validation_error | rate_limited | server_error | network_error | timeout. - The CLI never retries. Retry/backoff lives in the agent loop. For
rate_limited, sleepretryAfterseconds before retrying. - Mock server: set
ZOHO_INVENTORY_BASE_URL=http://127.0.0.1:<port>to redirect requests; setZOHO_INVENTORY_ACCOUNTS_URLto mock the OAuth refresh endpoint too. - DC routing:
ZOHO_INVENTORY_DCcontrols bothhttps://www.zohoapis.<dc>andhttps://accounts.zoho.<dc>. Mismatched DC →auth_invalid.
Every list action accepts --page and --per_page. Use --all to walk every page (the CLI iterates page_context.has_more_page). The CLI yields a JSON array of items; agents should never assume the API's response shape carries through --all.
- For non-trivial create/update payloads (line_items, addresses, custom_fields), prefer
--body '<json>'over individual flags. - For multipart uploads (
--file <path>): only six actions take it — seecommands/*.mjsfor which.
Auto-injected from ZOHO_INVENTORY_ORG_ID. Override with --organization-id <id> per command if needed. Never bury an org id inside --body — that won't work; Zoho reads it from the query string only.
The CLI auto-refreshes access tokens. Don't paste a static ZOHO_INVENTORY_API_KEY and expect it to last — they expire hourly. Set the trio (_REFRESH_TOKEN, _CLIENT_ID, _CLIENT_SECRET) and the CLI mints + caches access tokens for you.
npm test
Runs smoke (no network), integration (against test/_mock-server.mjs), and auth tests on the current Node version. CI runs the same on Node 20 and 22.
commands/*.mjs is generated from scripts/gen-resources.mjs. Hand-edits there get overwritten on the next regeneration. If you need to add a new flag or action, edit the RESOURCES table in the generator script and re-run node scripts/gen-resources.mjs && node scripts/gen-clify-meta.mjs.