Skip to content
This repository was archived by the owner on Jul 23, 2026. It is now read-only.
This repository was archived by the owner on Jul 23, 2026. It is now read-only.

List-endpoint filter flags drift from Zoho API docs — likely systemic across resources #1

Description

@codeyogi911

Summary

The auto-generated list-action flag sets are misaligned with what the Zoho Inventory API actually accepts. The packages list endpoint is the trigger — but the same pattern is likely repeated across most resources, since they were all generated from the same gen-resources.mjs heuristics.

Symptom: agents calling <resource> list with what looks like a working filter (--status, --reference_number, --customer_name, --date, --salesorder_id, --salesorder_number) hit the CLI's "BROKEN — falls back to client-side filter on the full list" path, even though Zoho's real API supports filtering server-side via different param names. Result: every list call pulls the entire dataset and filters in memory. Slow, wasteful, and opaque to the agent.

Concrete reproduction — packages list

CLI flag set today (scripts/gen-resources.mjs, packages entry):

  • --reference_number, --package_number, --salesorder_id, --salesorder_number, --customer_id, --customer_name, --status, --date, --search_text → all marked brokenListFilters, with comment "Zoho docs list a filter set (... filter_by, …) but in practice the exact-match forms of package_number, salesorder_number, salesorder_id are silently ignored". The conclusion was extended to every filter, not just those three.

What the docs actually specify (https://www.zoho.com/inventory/api/v1/packages/#list-all-packages):

Param Type Notes
filter_by string The canonical status filter. Allowed values: All, NotShipped, Shipped, Delivered. Not exposed by the CLI at all.
customer_id string Real exact-match filter — not broken.
search_text string Real free-text search.
sort_column string tracking_number / salesorder_number / package_number / date / created_time / last_modified_time / customer_name / customer_id / shipment_date / quantity / delivery_method.
packing_number_startswith / packing_number_contains long The CLI exposes bare --package_number, which Zoho ignores. The startswith/contains forms work.
salesorder_number_startswith / salesorder_number_contains long Same pattern — CLI exposes bare --salesorder_number, real API wants startswith/contains.
customer_name_startswith / customer_name_contains string Same pattern.
delivery_method_startswith / delivery_method_contains string Not exposed at all by CLI.
date_start / date_end date CLI exposes bare --date, which Zoho ignores.
shipment_date_start / shipment_date_end date Not exposed at all by CLI.

Live verification (run today against org_id=60033513768, India DC):

# Total packages: 319
zoho-inventory-cli packages list --all | jq length
# → 319

# With filter_by=Status.Shipped via direct curl: 83 packages — server-side filter WORKS
curl -s -H "Authorization: Zoho-oauthtoken $ACCESS" \
  "https://www.zohoapis.in/inventory/v1/packages?organization_id=$ORG&filter_by=Status.Shipped&per_page=200" \
  | jq '.packages | length'
# → 83

So filter_by is the headline param the CLI should expose, and the assumption that "all list filters are broken" is wrong — only the exact-match equivalents of startswith/contains are broken because they don't exist in the API in that form.

Request — full pass across all resources

Audit every list action in scripts/gen-resources.mjs against the live Zoho Inventory v1 docs (https://www.zoho.com/inventory/api/v1/) and the live API. For each list endpoint:

  1. Read the docs for the supported query params, including the filter_by enum and any *_startswith / *_contains / *_start / *_end variants.
  2. Probe each documented param against the live API to confirm it actually filters server-side (Zoho's docs aren't always honest, hence why this issue exists).
  3. Replace the resource entry in gen-resources.mjs:
    • Add a listFilters array with the params that genuinely work server-side, including filter_by (with allowed-values doc-string surfaced in --help).
    • Move the genuinely-broken bare-name shortcuts to brokenListFilters only if they have ergonomic value (better to drop them entirely and force callers to use the real param names).
    • Add sort_column / sort_order flags where supported.
  4. Regenerate, lint, ensure the tests still pass, and update knowledge/ with any per-resource gotchas discovered during probing.

Resources known or suspected to need the same fix: packages, shipment-orders, sales-orders, invoices, credit-notes, customer-payments, purchase-orders, bills, vendor-credits, delivery-challans, transfer-orders. Probably all of them.

Tests should cover at least one filter_by round-trip and one *_startswith round-trip per resource that has them.

Why this matters

Every misaligned flag adds wire payload + latency to scheduled jobs and skill runs. For the fix-coffee-delayed-shipments daily sweep at Fix Coffee, switching from packages list --all (319 records, 2.5s) to filter_by=Status.Shipped (83 records, ~0.7s) is a ~4× reduction. Across all resources with daily/weekly automations, the cumulative win is meaningful — and more importantly, the CLI stops teaching agents to ignore filters with its blanket "BROKEN" annotations.

Out of scope

  • The genuinely-broken bare-name filters can stay annotated as such — but the comment should say "Zoho ignores this exact-match form; use filter_by / *_startswith / *_contains instead", not the current blanket "all filters broken".
  • Body-vs-query parameter routing on POST/PUT is a separate concern (packages create already handles this correctly via queryFlags). Not part of this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions