jaz-clio 5.73.0 → 5.73.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,11 +20,11 @@ Node.js 18+. Works with [Jaz](https://jaz.ai) and [Juan Accounting](https://juan
20
20
  ## Contents
21
21
 
22
22
  - [Three ways in](#three-ways-in)
23
+ - [Auth](#auth)
23
24
  - [CLI](#cli)
24
25
  - [MCP server](#mcp-server)
25
26
  - [Skills](#skills)
26
27
  - [Jaz Kit · run your practice](#jaz-kit--run-your-practice)
27
- - [Auth](#auth)
28
28
  - [Semantic help-center search](#semantic-help-center-search-optional)
29
29
  - [Privacy](#privacy) · [Support](#support) · [License](#license)
30
30
 
@@ -38,6 +38,19 @@ Node.js 18+. Works with [Jaz](https://jaz.ai) and [Juan Accounting](https://juan
38
38
 
39
39
  On top of these, one layer for accountants closing real books across many companies: **[Jaz Kit](#jaz-kit--run-your-practice)**.
40
40
 
41
+ ## Auth
42
+
43
+ ```bash
44
+ clio auth login # sign in to Jaz in your browser (OAuth, the default)
45
+ clio auth whoami # verify
46
+ ```
47
+
48
+ `clio auth login` opens Jaz sign-in. The CLI and local MCP share the session and refresh its tokens automatically. Add `--no-browser` to open the printed link yourself on the same computer. Agents can use `--json`: the sign-in link goes to stderr, and stdout carries only the result and the organization choices.
49
+
50
+ Use `clio auth organizations --json` to list accessible organizations, `clio auth select <resourceId>` to select one, and `--org oauth:<resourceId>` on every organization-scoped command to pin it. `clio auth logout` removes the local session and keeps any API-key profiles; revoke the grant in Jaz to remove remote access.
51
+
52
+ API-key profiles, `--api-key`, `JAZ_API_KEY`, and PATs remain supported. Use `--org oauth:<resourceId>` for OAuth or `--org <label>` for a saved key profile (`clio auth add <key>`); either overrides an inherited `JAZ_API_KEY`. Without `--org`, the environment key still takes precedence. Do not combine `--api-key` with `--org`. Do not share OAuth storage or commit it to a workspace. Every command takes `--json` for structured output.
53
+
41
54
  ## CLI
42
55
 
43
56
  ```bash
@@ -49,9 +62,25 @@ clio jobs month-end --period 2026-03 # step-by-step close play
49
62
  clio magic create --file receipt.pdf # AI extracts, drafts the transaction
50
63
  clio invoices search --query 'status:unpaid AND $500+' # structured per-entity search
51
64
  clio ledger-find-fix preview --level TRANSACTIONS --input recode.json # find & fix (recode) across record types
65
+ clio approvals approve <resourceId> --entity invoices # approve a document waiting on you
66
+ clio sql preview "SELECT invoice_number, balance FROM invoices WHERE balance > 0 LIMIT 10" # read-only pseudo-SQL
67
+ clio report-templates list # the organization's saved report layouts
68
+ clio modules list # which features are switched on
69
+ clio navigate reports.profit-and-loss # deep link into the Jaz dashboard (offline)
52
70
  ```
53
71
 
54
- 76 command groups, 16 report types, 13 calculators, 12 job playbooks. Every command takes `--json`. Run `clio --help` for the full list.
72
+ 76 command groups, 17 report types, 13 calculators, 12 job playbooks. Every command takes `--json`. Run `clio --help` for the full list.
73
+
74
+ Command groups by area:
75
+
76
+ - **Sales and purchases**: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `sale-orders`, `purchase-orders`, `payments`, `unapplied-payments`, `approvals`, `drafts`, `schedulers`, `subscriptions`
77
+ - **Ledger and banking**: `journals`, `cash-in`, `cash-out`, `cash-transfer`, `cashflow`, `bank`, `bank-rules`, `reconciliations` (`recon`), `ledger-find-fix`, `quick-fix`, `fixed-assets` (`fa`)
78
+ - **Master data**: `accounts`, `contacts`, `contact-groups`, `items`, `purchase-items`, `catalogs`, `inventory` (`inv`), `tags`, `custom-fields`, `nano-classifiers`, `tax-profiles`, `currencies`, `currency-rates`, `capsules`, `capsule-recipes`
79
+ - **Claims**: `claims`, `claim-types`, `claim-profiles`, `posting-rules`, `employees`
80
+ - **Reports and data**: `reports`, `exports`, `export-records`, `report-templates`, `pseudo-sql` (`sql`), `filing-submissions`, `background-jobs`
81
+ - **Organization**: `org`, `org-users`, `references`, `modules` (`features`), `bookmarks`, `attachments`, `magic`, `jots`, `navigate` (`nav`), `help-center` (`hc`)
82
+ - **Offline**: `calc`, `capsule-transaction` (`ct`), `jobs`
83
+ - **Setup and tooling**: `auth`, `init`, `update`, `versions`, `version`, `health`, `completion`, `context`, `schema`, `resolve`, `mcp`, `mcp-call`, `serve`
55
84
 
56
85
  ### Foreign currency
57
86
 
@@ -82,12 +111,12 @@ that ends up in a journal.
82
111
 
83
112
  > **No install at all?** Claude.ai, ChatGPT, Cowork, and Microsoft Copilot Studio can use Jaz through the hosted connector. Add `https://mcp.jaz.ai/mcp` as a custom connector and sign in with OAuth, no key. The local setup below is for terminal use, scripting, and editors that run MCP servers as local processes.
84
113
 
85
- Run `clio auth login` once on this computer before enabling local MCP.
114
+ Run `clio auth login` once on this computer before enabling local MCP, then pin the organization with `--org` (`clio auth organizations` lists the IDs).
86
115
 
87
116
  **Claude Code**
88
117
 
89
118
  ```bash
90
- claude mcp add jaz -- npx jaz-clio mcp
119
+ claude mcp add jaz -- npx -y jaz-clio@latest mcp --org oauth:<resourceId>
91
120
  ```
92
121
 
93
122
  **Cursor · VS Code · Windsurf**
@@ -97,13 +126,13 @@ claude mcp add jaz -- npx jaz-clio mcp
97
126
  "mcpServers": {
98
127
  "jaz": {
99
128
  "command": "npx",
100
- "args": ["-y", "jaz-clio", "mcp"]
129
+ "args": ["-y", "jaz-clio@latest", "mcp", "--org", "oauth:<resourceId>"]
101
130
  }
102
131
  }
103
132
  }
104
133
  ```
105
134
 
106
- OAuth can reach the organizations granted at sign-in; name the organization on each call. Optional key-based access also supports comma-separated keys or a personal access token.
135
+ OAuth can reach the organizations granted at sign-in; `--org` pins one, and without it name the organization on each call. Optional key-based access also supports comma-separated keys or a personal access token.
107
136
 
108
137
  ```json
109
138
  { "env": { "JAZ_API_KEY": "jk-org1-key,jk-org2-key" } }
@@ -128,7 +157,7 @@ The workspace layer for closing real books, whether that is one company or fifty
128
157
  A close is not one conversation. Month-end runs many steps over several days, and an accountant serving eight clients runs it eight times, with eight different sets of bank accounts, materiality thresholds, and recurring entries. Jaz Kit gives each company a folder that remembers all of it, so no session re-asks what it should already know.
129
158
 
130
159
  ```
131
- /jk-setup create a company workspace, connect its key
160
+ /jk-setup create a company workspace, connect it with OAuth
132
161
  /jk-open acme load its context, verify the connection
133
162
  /jk-close 2026-06 run the close, resumable across sessions
134
163
  /jk-review approve the drafts waiting on you
@@ -142,15 +171,6 @@ Each company lives under `~/Documents/Jaz Kit/orgs/<company>/`, holding its clos
142
171
 
143
172
  Everything is drafted first, every record carries a link into Jaz for you to review, and an interrupted close resumes exactly where it stopped. Multi-company work needs this CLI, which you already have. Full guide in the [repository README](https://github.com/teamtinvio/jaz-ai#jaz-kit--run-your-practice).
144
173
 
145
- ## Auth
146
-
147
- ```bash
148
- clio auth login # Sign in to Jaz in your browser
149
- clio auth whoami # verify
150
- ```
151
-
152
- Pin an OAuth organization with `--org oauth:<resourceId>`. For optional API-key access, set `JAZ_API_KEY` or register a key using `clio auth add` and pass `--org <label>`. Every command takes `--json` for structured output.
153
-
154
174
  ## Semantic help-center search (optional)
155
175
 
156
176
  `search_help_center` runs keyword search over the bundled help-center corpus by default. Set `CLIO_HELP_CENTER_OPENAI_API_KEY` to add semantic search, which matches on intent rather than exact keywords: the CLI embeds only your query through the OpenAI embeddings API (`text-embedding-3-small`, the model the bundled index was built with) and merges both rankings. On an auth failure it warns once and falls back to keyword search. Use a project-scoped key restricted to embedding models with a low monthly cap. CLI only: MCPB installs ship without the embedding index and always use keyword search.
@@ -166,11 +186,3 @@ Runs on your machine. Calls go to the Jaz API over HTTPS. No telemetry, no data
166
186
  ## License
167
187
 
168
188
  [MIT](LICENSE)
169
-
170
- ## OAuth sign-in (default)
171
-
172
- Run `clio auth login` to open Jaz sign-in. CLI and local MCP share the session and refresh tokens automatically. Add `--no-browser` to open the printed link yourself on the same computer. Agents can use `--json`; the sign-in link is printed to stderr, and stdout contains only the result and organization choices.
173
-
174
- Use `clio auth organizations --json` to list accessible organizations, `clio auth select <resourceId>` to select one, and `--org oauth:<resourceId>` on every organization-scoped command to pin it. `clio auth logout` removes the local session without deleting API-key profiles; revoke its grant in Jaz to remove remote access.
175
-
176
- API-key profiles, `--api-key`, `JAZ_API_KEY`, and PATs remain supported. Use `--org oauth:<resourceId>` for OAuth or `--org <label>` for a saved key profile; either overrides an inherited `JAZ_API_KEY`. Without `--org`, the environment key still takes precedence. Do not combine `--api-key` with `--org`. Do not share OAuth storage or commit it to a workspace.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-api
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill whenever you call, debug, or review code that touches the Jaz
6
6
  REST API. Covers field names, response shapes, 159 production gotchas, error
@@ -215,7 +215,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
215
215
  73. **Capsules PUT requires `resourceId` + `capsuleTypeResourceId`** — Even for partial updates, `PUT /capsules/:id` requires `resourceId` and `capsuleTypeResourceId` in the body. Omitting either causes 422 or "Capsule type not found". Use read-modify-write pattern: GET current capsule, merge updates, PUT full payload. Clio handles this automatically.
216
216
 
217
217
  ### Cash Entry Response Shape (CRITICAL)
218
- 74. **Cash-in/out/transfer CREATE returns `parentEntityResourceId`** — The resourceId in the POST response (`{ data: { resourceId: "X" } }`) is the journal header's `parentEntityResourceId`. This ID is used for DELETE (`DELETE /cash-entries/X`). But it is **NOT** the same ID used for GET (`GET /cash-in-entries/:id`). GET expects the cashflow-transaction `resourceId` from the LIST response. Three different IDs exist per cash entry: `parentEntityResourceId` (from CREATE + in LIST), `resourceId` (cashflow-transaction ID, from LIST — use for GET), `businessTransactionResourceId` (underlying journal ID — do NOT use for anything).
218
+ 74. **Cash-in/out/transfer CREATE returns `parentEntityResourceId`**: the resourceId in the POST response (`{ data: { resourceId: "X" } }`) is the journal header's `parentEntityResourceId`. This ID is used for DELETE (`DELETE /cash-entries/X`) and PUT. GET (`GET /cash-in-entries/:id`) accepts either the cashflow-transaction `resourceId` from the LIST response or this `parentEntityResourceId`. Three different IDs exist per cash entry: `parentEntityResourceId` (from CREATE + in LIST), `resourceId` (cashflow-transaction ID, from LIST, also accepted by GET), `businessTransactionResourceId` (underlying journal ID, do NOT use for anything).
219
219
  75. **Cash-in/out/transfer LIST/GET return cashflow-transaction shape** — NOT journal shape. Key field differences from journals: `transactionReference` (NOT `reference`), `transactionStatus` (NOT `status` — values: `ACTIVE`/`VOID`), `valueDate` is epoch ms (NOT ISO string), no `journalEntries` array, has `direction` (`PAYIN`/`PAYOUT`), has nested `account` object with bank name, has `businessTransactionType` (`JOURNAL_DIRECT_CASH_IN`/`JOURNAL_DIRECT_CASH_OUT`/`JOURNAL_CASH_TRANSFER`).
220
220
  76. **Cash-in/out/transfer search uses `/cashflow-transactions/search`** — Filter by `businessTransactionType: { eq: "JOURNAL_DIRECT_CASH_IN" }` (or `JOURNAL_DIRECT_CASH_OUT` or `JOURNAL_CASH_TRANSFER`). Other useful filters: `organizationAccountResourceId` (bank account), `businessTransactionReference` (reference), `valueDate` (date range). The search endpoint is shared across all cashflow transaction types.
221
221
  77. **DELETE for cash entries uses `/cash-entries/:id`** — NOT the individual resource paths. The ID used is the `parentEntityResourceId` (= the resourceId returned by CREATE). This is a shared endpoint for all cash entry types (cash-in, cash-out, cash-transfer).
@@ -329,7 +329,7 @@ Bills, invoices, and credit notes share identical mandatory field specs. Adding
329
329
  94. **Scheduled transaction search does NOT support `createdAt` sort** — `POST /scheduled-transaction/search` sort fields: `startDate`, `nextScheduleDate`, etc. Default to `startDate` DESC. This is a cross-entity search across all scheduled types (invoices, bills, journals, subscriptions). Filter by `businessTransactionType` (SALE, PURCHASE, JOURNAL) and/or `schedulerType` (RECURRING, SUBSCRIPTION) to narrow results.
330
330
 
331
331
  ### Contact Groups
332
- 96. **Contact groups have `associatedContacts` array** — Each group contains `{ name, resourceId, associatedContacts: [{ name, resourceId }] }`. Search via `POST /contact-groups/search`. Known bug: PUT returns 500 (Rule 46).
332
+ 96. **Contact groups have `associatedContacts` array**: each group contains `{ name, resourceId, associatedContacts: [{ name, resourceId }] }`. Search via `POST /contact-groups/search`.
333
333
 
334
334
  ### Inventory
335
335
  97. **Inventory balances: one item or all.** One item: `GET /inventory-item-balance/:itemResourceId` (`get_inventory_balance`) returns `{ itemResourceId, latestAverageCostAmount, baseQty, baseUnit }`; the id is the ITEM resourceId, not an inventory-specific ID. All items: `GET /inventory-balances/:balanceStatus` (`list_inventory_balances`, `clio inventory balances --status`) with `balanceStatus` one of `ALL`, `AVAILABLE`, `FULLY_DRAWN` (anything else is 422); rows carry `itemCode`, `internalName`, `totalQuantity`, `baseUnit`, `averageCostAmount`, `balanceAmount`. The API answers an empty result with 404; the tool and CLI return it as `data: []`. `offset` is a page number here, though the spec says row (probed live 2026-09-23).
@@ -374,7 +374,7 @@ Bills, invoices, and credit notes share identical mandatory field specs. Adding
374
374
  111. **Quick-fix uses `tags` (string array) — e.g., `"tags": ["Q1"]`** — The `attributes` object in quick-fix transaction endpoints accepts `tags` as a string array (e.g., `"tags": ["Q1"]`). `tag` (singular) is silently ignored. This matches the `tags` array format used on create/update for all transaction types. The CLI `--tag` flag auto-wraps to `tags: [name]`.
375
375
 
376
376
  ### Sub-Resource Response Shapes
377
- 112. **Invoice/bill payment & credit sub-resources return raw arrays** — `GET /invoices/:id/payments` and `GET /bills/:id/payments` return `[{paymentRecord}, ...]` — NOT `{data: [...]}`. Same for `GET /invoices/:id/credits` and `GET /bills/:id/credits`. The CLI wraps these into `{data: [...]}` for consistency. `DELETE /invoices/:id/credits/:creditsAppliedResourceId` reverses a credit application.
377
+ 112. **Invoice/bill payment & credit sub-resources: two shapes** (read from the API source; payments and the empty-credits case measured raw 2026-09-24). `GET /invoices/:id/payments` and `GET /bills/:id/payments` return `{ data: [{paymentRecord}, ...] }` (Rule 64). `GET /invoices/:id/credits` and `GET /bills/:id/credits` return `{ TotalElements, data: [...] }` when credits are applied but a BARE `[]` when none are. The CLI and tools normalize all of these to `{data: [...]}`. `DELETE /invoices/:id/credits/:creditsAppliedResourceId` reverses a credit application.
378
378
 
379
379
  ### Nano-Classifier API
380
380
  113. **Nano-classifier API gotchas** — CREATE uses `classes: string[]` (NOT `classNames` or `[{className}]`). `printable: boolean` is required — defaults to `false` (most classifiers are not printable). GET single is double-wrapped: `{data: {data: [...], totalElements, totalPages}}` — extract the first element from the inner paginated response. GET/LIST response returns classes as `[{className, resourceId}]` (objects), while CREATE accepts plain `string[]`.
@@ -20,7 +20,8 @@ employee** automatically (server resolves it at enqueue) — no `search_claims`
20
20
  don't pre-check). No bound employee on the uploader (a service / shared-key identity) →
21
21
  the server leaves it unbound; relay that ("not set up for claims"), don't invent one. The
22
22
  OCR'd draft may also carry no `reference` — if a later submit returns
23
- `CLAIM_REFERENCE_REQUIRED_AT_SUBMIT`, set one via `update_claim`.
23
+ `CLAIM_REFERENCE_REQUIRED_AT_SUBMIT`, read the next number with `get_next_reference` (type
24
+ `CLAIM`) and pass it as `reference` on `update_claim` (it has no autoReference).
24
25
 
25
26
  ## Claim records (`claims` + `claim_processing` namespaces)
26
27
 
@@ -787,7 +787,7 @@ Same shape as list items, wrapped in `{ data: {...} }`. Use the `resourceId` fro
787
787
  ### PUT /api/v1/cash-in-entries/:resourceId
788
788
  ### PUT /api/v1/cash-out-entries/:resourceId
789
789
 
790
- Same request body as POST. Use cashflow-transaction `resourceId` from LIST.
790
+ Same request body as POST. Use the `parentEntityResourceId` (= the CREATE-returned resourceId).
791
791
 
792
792
  ### DELETE /api/v1/cash-entries/:resourceId
793
793
 
@@ -801,7 +801,7 @@ Shared delete endpoint for ALL cash entry types (cash-in, cash-out, cash-transfe
801
801
  **CRITICAL ID gotcha (verified via live testing)**:
802
802
  - CREATE returns `resourceId = A` (this is `parentEntityResourceId`)
803
803
  - LIST returns `resourceId = B` (cashflow-transaction ID), `parentEntityResourceId = A`
804
- - GET expects `B` (cashflow-transaction ID)
804
+ - GET accepts `B` (cashflow-transaction ID) or `A` (parentEntityResourceId; a transfer's two rows share one `A`, so GET by `A` returns the first)
805
805
  - DELETE expects `A` (parentEntityResourceId, via `/cash-entries/A`)
806
806
  - `businessTransactionResourceId = C` (underlying journal ID) — do NOT use for any CRUD operation
807
807
 
@@ -1056,7 +1056,7 @@ Same cashflow-transaction response shape as cash-in/out list. `businessTransacti
1056
1056
 
1057
1057
  ### GET /api/v1/cash-transfers/:resourceId
1058
1058
 
1059
- Use cashflow-transaction `resourceId` from LIST. Returns same shape wrapped in `{ data: {...} }`.
1059
+ Accepts the cashflow-transaction `resourceId` from LIST or the `parentEntityResourceId` from CREATE (both legs share it; GET by it returns the first). Returns same shape wrapped in `{ data: {...} }`.
1060
1060
 
1061
1061
  **Cash transfers have NO update (PUT) endpoint.**
1062
1062
 
@@ -2345,37 +2345,40 @@ Update an existing payment record. All fields optional — only included fields
2345
2345
 
2346
2346
  ## 19b. Invoice/Bill Sub-Resource Endpoints
2347
2347
 
2348
- ### GET /api/v1/invoices/{resourceId}/payments — Raw array response
2348
+ ### GET /api/v1/invoices/{resourceId}/payments
2349
2349
 
2350
2350
  ```json
2351
- // Response (RAW ARRAY — no {data: [...]} wrapper):
2352
- [
2353
- {
2354
- "resourceId": "uuid-payment",
2355
- "paymentAmount": 2250.00,
2356
- "transactionAmount": 2250.00,
2357
- "valueDate": 1709251200000,
2358
- "paymentMethod": "BANK_TRANSFER",
2359
- "reference": "PAY-001"
2360
- }
2361
- ]
2351
+ // Response ({data: [...]} envelope):
2352
+ {
2353
+ "data": [
2354
+ {
2355
+ "resourceId": "uuid-payment",
2356
+ "paymentAmount": 2250.00,
2357
+ "transactionAmount": 2250.00,
2358
+ "valueDate": 1709251200000,
2359
+ "paymentMethod": "BANK_TRANSFER",
2360
+ "reference": "PAY-001"
2361
+ }
2362
+ ]
2363
+ }
2362
2364
  ```
2363
2365
 
2364
- Same for `GET /bills/{resourceId}/payments`, `GET /invoices/{resourceId}/credits`, `GET /bills/{resourceId}/credits`.
2366
+ Same envelope for `GET /bills/{resourceId}/payments`.
2365
2367
 
2366
- **CRITICAL**: These sub-resource endpoints return raw arrays, NOT `{data: [...]}`. The CLI wraps them into `{data: [...]}` for consistency.
2368
+ **CRITICAL**: `GET /invoices/{resourceId}/credits` and `GET /bills/{resourceId}/credits` differ:
2369
+ `{ "TotalElements": n, "data": [...] }` when credits are applied, but a BARE `[]` when none
2370
+ are (read from the API source; the empty case measured raw 2026-09-24). The CLI and tools normalize both to `{data: [...]}`.
2367
2371
 
2368
2372
  ---
2369
2373
 
2370
- ## 19c. Request Changes (REST only — no CLI or MCP wrapper)
2374
+ ## 19c. Request Changes
2371
2375
 
2372
2376
  Sends a **submitted** record back to its creator for edits: the record returns to draft, its
2373
2377
  approval markers are cleared, and `message` is posted as the first comment on a new
2374
2378
  collaboration thread. Records in any other state are skipped and reported in the response.
2375
2379
 
2376
- > **No wrapper exists.** These 18 routes have no `clio` subcommand, no MCP tool, and no
2377
- > `src/core/api/` client function. Call them with a raw HTTP request — do not go looking for a
2378
- > tool that does not exist.
2380
+ > **Wrapped.** MCP tools `request_document_changes` / `bulk_request_document_changes`, CLI
2381
+ > `clio approvals request-changes` / `clio approvals bulk-request-changes`.
2379
2382
 
2380
2383
  Nine entities, each with a single-record and a bulk form:
2381
2384
 
@@ -2440,6 +2443,34 @@ the job was accepted.
2440
2443
 
2441
2444
  ---
2442
2445
 
2446
+ ## 19d. Approve
2447
+
2448
+ Approves a record awaiting approval. **Irreversible**: it posts the ledger (and for invoices and
2449
+ bills also confirms a linked order and consumes the document reference). There is nothing to undo, and approving is one-shot
2450
+ (a record not awaiting approval, including an already-approved one, is refused).
2451
+ MCP tools `approve_documents` / `bulk_approve_documents`, CLI `clio approvals approve` /
2452
+ `clio approvals bulk-approve`. Four entities: `invoices`, `bills`, `customer-credit-notes`,
2453
+ `supplier-credit-notes` (claims approve through their own claims routes).
2454
+
2455
+ | Form | Route | Response |
2456
+ |------|-------|----------|
2457
+ | Single | `POST /api/v1/{entity}/:resourceId/approve` (no body) | 200, `{ "data": { "records": [ { resourceId, status, approvalStatus, isSuccess, failureReason, errorCode } ] } }` |
2458
+ | Bulk | `POST /api/v1/{entity}/bulk-approve` | 202, job handle (same shape as 19c bulk); poll `POST /api/v1/background-jobs/search` |
2459
+
2460
+ - Bulk body `{ "resourceIds": [...] }`: 1-100 **unique** UUIDs. Over 100 or a duplicate is 422
2461
+ with nothing written.
2462
+ - Single form: an id not found in your organization is 404.
2463
+ - An id not found in your organization rejects the **whole** bulk batch with 422 and no job is
2464
+ dispatched: fix the list and retry.
2465
+ - Bulk: records not awaiting approval are skipped and reported on the job tasks; only a foreign
2466
+ id fails the batch.
2467
+ - Refusal channel differs: invoices/bills return 422 on a refused single approve; credit notes
2468
+ return 200 with `isSuccess: false` while `approvalStatus` still reads the document's state.
2469
+ Check `isSuccess`, never `approvalStatus`.
2470
+ - On a timeout or 500, read the record back and check its approval status before retrying.
2471
+
2472
+ ---
2473
+
2443
2474
  ## 20. Nano-Classifier CRUD
2444
2475
 
2445
2476
  ### POST /api/v1/nano-classifiers — Create
@@ -869,7 +869,7 @@ The same applies on update: `PUT /cash-in-entries/:id` with `saveAsDraft: true`
869
869
 
870
870
  **"INACTIVE_OR_DELETED_ACCOUNT"** — The account referenced in the update is deleted or inactive. Verify the account UUID is valid and active.
871
871
 
872
- **"Cannot update ACTIVE entry"** — Journal or cash entry is already active. Must void and recreate to change.
872
+ **"Cannot update ACTIVE entry"**: a per-record quick-fix failure. Do NOT void and recreate; edit the record with its own update tool: `update_invoice` / `update_bill` / `update_cash_in` / `update_cash_out` / `update_journal`.
873
873
 
874
874
  **"TRANSACTION_LOCKED"** — Transaction is in a locked period. Cannot update.
875
875
 
@@ -914,7 +914,7 @@ Two of the seven never reach you through this path: a zero `adjustmentValue` and
914
914
 
915
915
  ### Sub-Resource Response Errors
916
916
 
917
- **`Cannot read property 'data'` / TypeError** — Invoice/bill sub-resource endpoints (`GET /invoices/:id/payments`, `GET /invoices/:id/credits`, etc.) return raw arrays `[{...}]`, NOT `{data: [...]}`. Trying to access `.data` on the response fails. Wrap the raw array yourself.
917
+ **`Cannot read property 'data'` / TypeError**: `GET /invoices/:id/credits` and `GET /bills/:id/credits` return a BARE `[]` when no credits are applied (else `{TotalElements, data}`), so `.data` on the empty case fails. Accept both shapes. The `/payments` sub-resources always answer `{data: [...]}`.
918
918
 
919
919
  ---
920
920
 
@@ -14,7 +14,7 @@ Key capabilities: draft/approval workflows, multi-currency (auto-fetch ECB rates
14
14
 
15
15
  If payment date equals invoice date, it's recorded as a cash transaction (not AR). Transaction fees are deducted from cash received, and a payment `adjustment` shifts the cash leg further (net cash = paymentAmount - feesCharged + feesCollected +/- adjustmentValue) without touching AR. RGL = `(Invoice payment / Transaction Rate) - (Cash received / Payment Rate)`.
16
16
 
17
- **API**: CRUD `GET/POST/PUT/DELETE /invoices`, `POST /invoices/search`, `POST /invoices/:id/payments`, `GET /invoices/:id/payments`, `POST /invoices/:id/credits`, `GET /invoices/:id/download`, `POST/GET/DELETE /invoices/:id/attachments`, `PUT /invoices/:id/approve`, `POST /scheduled/invoices` (CRUD), `POST /scheduled/subscriptions` (recurring). Generic payment ops: `GET/PUT/DELETE /payments/:id`. **Starting from a PDF/JPG attachment?** Use `POST /magic/createBusinessTransactionFromAttachment` instead — Jaz Magic handles extraction & autofill (see AI Agents section).
17
+ **API**: CRUD `GET/POST/PUT/DELETE /invoices`, `POST /invoices/search`, `POST /invoices/:id/payments`, `GET /invoices/:id/payments`, `POST /invoices/:id/credits`, `GET /invoices/:id/download`, `POST/GET/DELETE /invoices/:id/attachments`, `POST /invoices/:id/approve`, `POST /scheduled/invoices` (CRUD), `POST /scheduled/subscriptions` (recurring). Generic payment ops: `GET/PUT/DELETE /payments/:id`. **Starting from a PDF/JPG attachment?** Use `POST /magic/createBusinessTransactionFromAttachment` instead: Jaz Magic handles extraction & autofill (see AI Agents section).
18
18
 
19
19
  ---
20
20
 
@@ -40,7 +40,7 @@ Key capabilities: bill receipts (short-form template creating bill + payment tog
40
40
 
41
41
  Transaction fees are added to cash spent (not deducted like invoices), and a payment `adjustment` shifts the cash leg further without touching AP. RGL = `(Cash spent / Payment rate) - (Bill payment / Transaction rate)`.
42
42
 
43
- **API**: CRUD `GET/POST/PUT/DELETE /bills`, `POST /bills/search`, `POST /bills/:id/payments`, `GET /bills/:id/payments`, `POST /bills/:id/credits`, `POST/GET/DELETE /bills/:id/attachments`, `PUT /bills/:id/approve`, `POST /scheduled/bills` (CRUD). Generic payment ops: `GET/PUT/DELETE /payments/:id`. **Starting from a PDF/JPG attachment?** Use `POST /magic/createBusinessTransactionFromAttachment` instead — Jaz Magic handles extraction & autofill (see AI Agents section).
43
+ **API**: CRUD `GET/POST/PUT/DELETE /bills`, `POST /bills/search`, `POST /bills/:id/payments`, `GET /bills/:id/payments`, `POST /bills/:id/credits`, `POST/GET/DELETE /bills/:id/attachments`, `POST /bills/:id/approve`, `POST /scheduled/bills` (CRUD). Generic payment ops: `GET/PUT/DELETE /payments/:id`. **Starting from a PDF/JPG attachment?** Use `POST /magic/createBusinessTransactionFromAttachment` instead: Jaz Magic handles extraction & autofill (see AI Agents section).
44
44
 
45
45
  ---
46
46
 
@@ -179,7 +179,7 @@ Statement amounts are recorded in the bank account's currency — no auto-conver
179
179
 
180
180
  Workflow for draft invoices and bills requiring admin sign-off before activation. Three user roles: Admins (approve + create active), Preparers (submit drafts for approval), Members (submit own drafts only). Status progression: Draft → For Approval → Approved (active). Approval PDFs capture Submitted By / Approved By audit trail.
181
181
 
182
- **API**: `PUT /invoices/:id/approve`, `PUT /bills/:id/approve`
182
+ **API**: `POST /{invoices|bills|customer-credit-notes|supplier-credit-notes}/:id/approve` and `/bulk-approve` (irreversible: posts the ledger), `POST /{entity}/:id/request-changes` (endpoints.md sections 19c, 19d)
183
183
 
184
184
  ---
185
185
 
@@ -327,10 +327,10 @@ PUT URL: `/cash-in-entries/:parentEntityResourceId` (or `/cash-out-entries/:id`)
327
327
 
328
328
  ```
329
329
  CREATE → { resourceId: "A" } ← This is parentEntityResourceId
330
- LIST → { resourceId: "B", ← This is the cashflow-transaction ID (use for GET)
330
+ LIST → { resourceId: "B", ← This is the cashflow-transaction ID (GET accepts it)
331
331
  businessTransactionResourceId: "C", ← underlying journal ID (don't use)
332
332
  parentEntityResourceId: "A" } ← matches CREATE response
333
- GET → expects "B" (cashflow-transaction ID)
333
+ GET → accepts "B" (cashflow-transaction ID) or "A" (parentEntityResourceId)
334
334
  PUT → expects "A" (parentEntityResourceId) — body needs resourceId: "A"
335
335
  DELETE → expects "A" (parentEntityResourceId, via /cash-entries/:id)
336
336
  ```
@@ -3,13 +3,13 @@
3
3
  > **The endpoints clio wraps — the REST surface is larger.** This file catalogues roughly 200
4
4
  > paths, organized by resource, including undocumented endpoints, magic AI features, admin
5
5
  > APIs, and advanced search/filter syntax. The committed OpenAPI spec (`spec/openapi.yaml`)
6
- > carries 454 paths / 381 operations and is the authoritative list; check it before concluding
6
+ > carries 466 spec paths and 594 spec operations and is the authoritative list; check it before concluding
7
7
  > an endpoint does not exist. For request/response examples of core endpoints, see
8
8
  > endpoints.md.
9
9
  >
10
10
  > **Paths below are written without the `/api/v1` prefix.** Every one of them is really
11
11
  > `/api/v1/<path>`. Recent additions not yet folded into the tables are listed at the end
12
- > under "2026-08 additions".
12
+ > under "Additions since 2026-07-11".
13
13
 
14
14
  ---
15
15
 
@@ -48,9 +48,9 @@
48
48
  | DELETE | `/invoices/:resourceId` | Delete invoice |
49
49
  | GET | `/invoices/:resourceId/download` | Download PDF |
50
50
  | POST | `/invoices/:resourceId/payments` | Record payment(s) |
51
- | GET | `/invoices/:resourceId/payments` | List recorded payments — **raw array response** |
51
+ | GET | `/invoices/:resourceId/payments` | List recorded payments (`{data: [...]}`) |
52
52
  | POST | `/invoices/:resourceId/credits` | Apply credit note(s) |
53
- | GET | `/invoices/:resourceId/credits` | List applied credits — **raw array response** |
53
+ | GET | `/invoices/:resourceId/credits` | List applied credits (**bare `[]` when none applied**, else `{TotalElements, data}`) |
54
54
  | DELETE | `/invoices/:resourceId/credits/:creditsAppliedResourceId` | Reverse credit |
55
55
  | GET | `/invoices/:resourceId/attachments` | List attachments |
56
56
  | POST | `/invoices/:resourceId/attachments` | Upload attachment |
@@ -705,7 +705,7 @@ These features exist in the Jaz platform and may affect API responses or cause u
705
705
  - Bills and invoices can be submitted for approval workflow
706
706
  - Only admin users (AP permission) can approve submitted bills
707
707
  - API-created transactions with `saveAsDraft: false` bypass approval workflow
708
- - Approval records are read-only via API
708
+ - Approve and request-changes are writable via API: `POST /{entity}/:resourceId/approve` + `bulk-approve` (invoices, bills, both credit notes; irreversible) and `request-changes` (endpoints.md sections 19c, 19d)
709
709
 
710
710
  ### Lock Dates
711
711
  - Organizations can set a lock date preventing changes before that cutoff
@@ -779,8 +779,8 @@ See endpoints.md section 25 for request/response shapes and the `refs` grammar (
779
779
 
780
780
  ## Additions since 2026-07-11
781
781
 
782
- Live routes added after the tables above were last regenerated. None has a `clio` subcommand
783
- or an MCP tool — call them with a raw request.
782
+ Live routes added after the tables above were last regenerated. Unless a subsection names its
783
+ wrapper, it has no `clio` subcommand or MCP tool: call it with a raw request.
784
784
 
785
785
  ### Request changes (18) — 2026-08-06
786
786
 
@@ -788,7 +788,8 @@ or an MCP tool — call them with a raw request.
788
788
  `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `purchase-orders`,
789
789
  `purchase-requests`, `sale-orders`, `sale-quotes`. Claims uses a different bulk shape:
790
790
  `POST /claims/:resourceId/request-changes` + `POST /claims/bulk/request-changes`.
791
- Bodies and per-record outcome semantics: endpoints.md section 19c.
791
+ Bodies and per-record outcome semantics: endpoints.md section 19c. Wrapped by
792
+ `request_document_changes` / `bulk_request_document_changes` and `clio approvals`.
792
793
 
793
794
  ### Payments, bulk and batch (9) — 2026-08-13
794
795
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-cli
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill when running Clio CLI commands, building shell scripts with
6
6
  Clio, debugging auth issues, understanding --json output, paginating results,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-conversion
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill when migrating accounting data into Jaz — importing from Xero,
6
6
  QuickBooks, Sage, MYOB, or Excel exports. Covers the full conversion pipeline:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-kit
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill when an accountant, bookkeeper, or owner is running real books
6
6
  in Jaz across one or more organizations from the terminal — setting up a
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-pseudo-sql
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill when answering ad-hoc data questions that aren't covered by
6
6
  download_export (canonical reports — anomaly, audit, aging, P&L, BS, GL,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-jobs
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill for recurring accounting workflows — month/quarter/year-end
6
6
  close, bank reconciliation, GST/VAT filing, payment runs, credit control,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-recipes
3
- version: 5.73.0
3
+ version: 5.73.2
4
4
  description: >-
5
5
  Use this skill when modeling complex multi-step accounting transactions —
6
6
  anything that spans multiple periods, involves changing amounts, or requires
@@ -4,11 +4,11 @@ Jaz accounting guidance for this workspace. Load the installed Jaz skills for de
4
4
 
5
5
  ## Discovery
6
6
 
7
- Jaz exposes **381 tools across 46 namespaces**. Your tool list shows **3, 45, or 371** entries depending on packaging — **never infer capability from its length.**
7
+ Jaz exposes **381 tools across 46 namespaces**. Your tool list shows **3, 46, or 381** entries depending on packaging — **never infer capability from its length.**
8
8
 
9
9
  - **3** — `search_tools(query)` → `describe_tools(names)` → `execute_tool(name, args)`. Empty query returns the namespace map.
10
- - **45** — namespace routers; call one with `{ operation, arguments }`. Its description lists its operations.
11
- - **371** — call operations directly by name.
10
+ - **46** — namespace routers; call one with `{ operation, arguments }`. Its description lists its operations.
11
+ - **381** — call operations directly by name.
12
12
 
13
13
  `describe_capabilities` returns the capability map on all three. **Call it before telling the user Jaz cannot do something.**
14
14