jaz-clio 5.67.0 → 5.69.0

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-api
3
- version: 5.67.0
3
+ version: 5.69.0
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
@@ -138,7 +138,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
138
138
  35d. **Tags are `tags: string[]`** on ALL transaction create/update: invoices, bills, customer CNs, supplier CNs, journals, cash-in, cash-out, cash transfers. CLI uses `--tag <name>` (singular, wrapped to array). API accepts the array directly.
139
139
 
140
140
  ### Nano Classifiers
141
- 35e. **ClassifierConfig on line items**: `classifierConfig: [{ resourceId: "<capsuleTypeId>", type: "invoice"|"bill", selectedClasses: [{ className: "Class A", resourceId: "<classId>" }], printable: true }]`. Applies to line items on invoices, bills, credit notes, journal entries, and cash entry details. Create capsule types first via `POST /capsule-types`, then reference them in classifierConfig.
141
+ 35e. **ClassifierConfig on line items**: `classifierConfig: [{ resourceId: "<capsuleTypeId>", type: "invoice"|"bill", selectedClasses: [{ className: "Class A", resourceId: "<classId>" }], printable: true }]`. Applies to line items on invoices, bills, credit notes, journal entries, and cash entry details. Create capsule types first via `POST /capsule-types`, then reference them in classifierConfig. A selected class needs `resourceId` unless it sends `entityResourceId` instead (a classifier whose options are customers, suppliers, contacts, employees or users). Quick fix and Ledger Find & Fix add `{ resourceId, deleted: true }` to remove one classifier and leave unnamed ones as they are (rule 107).
142
142
 
143
143
  ### Reports
144
144
  36. **Report field names differ by type** — this is the most error-prone area:
@@ -192,13 +192,13 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
192
192
  ### Jaz Magic — Extraction & Autofill
193
193
  57. **When the user starts from an attachment, always use Jaz Magic** — if the input is a PDF, JPG, or any document image (invoice, bill, receipt), the correct path is `POST /magic/createBusinessTransactionFromAttachment`. Do NOT manually construct a `POST /invoices` or `POST /bills` payload from an attachment — Jaz Magic handles the entire extraction-and-autofill pipeline server-side: OCR, line item detection, contact matching, CoA auto-mapping via ML learning, and draft creation with all fields pre-filled. Only use `POST /invoices` or `POST /bills` when building transactions from structured data (JSON, CSV, database rows) where the fields are already known. If you hold the invoice/bill as raw HTML (e.g. an email body), pass it via `sourceType: "HTML"` with an `html` field — the backend renders it to a PDF then extracts, so you do NOT need to save it to a file first.
194
194
  58. **Three upload modes with different content types** — `sourceType: "FILE"` requires **multipart/form-data** with `sourceFile` blob (JSON body fails with 400 "sourceFile is a required field"). `sourceType: "URL"` accepts **application/json** with `sourceURL` string. `sourceType: "HTML"` accepts the raw HTML body in an `html` field (JSON or multipart) — the backend renders it to a PDF, then extracts (use this for an email body you already hold; no file needed). The OAS only documents URL mode — FILE and HTML modes are undocumented there.
195
- 58a. **The server FETCHES the source — a local path is not a source at any spelling** — in URL mode `sourceURL` is opened by the Jaz server, so it must be reachable from the public internet; in FILE mode you send the bytes yourself as a multipart blob. A path on the calling machine (`/mnt/user-data/uploads/x.zip`, `/tmp/invoice.pdf`) is neither: it is not a URL the server can open, and putting it in `sourceURL` — or in an MCP `file.download_url`, which the HOST populates and a caller must never author — fails after a round-trip with no indication that re-spelling the path is hopeless. Same rule for `classify_documents`: its `source` is fetched server-side, and a local folder/zip path is accepted only when the client is running on the caller's own machine. When you hold bytes but no shareable URL, switch to FILE mode, upload in the dashboard and pass the `attachmentId`, or ask for a Dropbox/Drive/OneDrive share link — do not retry the path.
196
- 59. **Three required fields + one optional**: the source (`sourceFile` multipart blob — NOT `file` — for FILE, `sourceURL` for URL, or `html` for HTML), `businessTransactionType` (`"INVOICE"`, `"BILL"`, `"CUSTOMER_CREDIT_NOTE"`, or `"SUPPLIER_CREDIT_NOTE"` — `EXPENSE` rejected), `sourceType` (`"FILE"`, `"URL"`, or `"HTML"`). For HTML mode, `html` is the raw HTML string (max 5 MB). Optional: `uploadMode` (`"SEPARATE"` default, or `"MERGED"` for a single PDF containing multiple documents — the backend splits it via boundary detection before extraction). All required fields are validated server-side. **CRITICAL: multipart form field names are camelCase** — `businessTransactionType`, `sourceType`, `sourceFile`, `uploadMode`, NOT snake_case. Using `business_transaction_type` returns 422 "businessTransactionType is a required field". The File blob must include a filename and correct MIME type (e.g. `application/pdf`, `image/jpeg`) — bare `application/octet-stream` blobs are rejected with 400 "Invalid file type".
195
+ 58a. **The server FETCHES the source; a local path is not a source at any spelling**: in URL mode `sourceURL` is opened by the Jaz server, so it must be reachable from the public internet; in FILE mode you send the bytes yourself as a multipart blob. A path on the calling machine (`/mnt/user-data/uploads/x.zip`, `/tmp/invoice.pdf`) is neither: it is not a URL the server can open, and putting it in `sourceURL` (or in an MCP `file.download_url`, which the HOST populates and a caller must never author) fails after a round-trip with no indication that re-spelling the path is hopeless. Same rule for `classify_documents`: its `source` is fetched server-side, and a local folder/zip path is accepted only when the client is running on the caller's own machine. When you hold bytes but no shareable URL, switch to FILE mode or ask for a Dropbox/Drive/OneDrive share link; do not retry the path.
196
+ 59. **Three required fields + one optional**: the source (`sourceFile` multipart blob, NOT `file`, for FILE, `sourceURL` for URL, or `html` for HTML), `businessTransactionType` (`"INVOICE"`, `"BILL"`, `"CUSTOMER_CREDIT_NOTE"`, `"SUPPLIER_CREDIT_NOTE"`, `"SALE_QUOTE"`, `"SALE_ORDER"`, `"PURCHASE_REQUEST"`, or `"PURCHASE_ORDER"`; `EXPENSE` rejected; a quote/request lands DRAFT, an order lands PENDING until the order update's `isPendingToActive*` flag), `sourceType` (`"FILE"`, `"URL"`, or `"HTML"`). For HTML mode, `html` is the raw HTML string (max 5 MB). Optional: `uploadMode` (`"SEPARATE"` default, or `"MERGED"` for a single PDF containing multiple documents; the backend splits it via boundary detection before extraction; refused for the four quote/order/request types) and `internalNotes` (max 3000 characters, set on the created record). Max 10 MB per file. All required fields are validated server-side. **CRITICAL: multipart form field names are camelCase**: `businessTransactionType`, `sourceType`, `sourceFile`, `uploadMode`, NOT snake_case. Using `business_transaction_type` returns 422 "businessTransactionType is a required field". The File blob must include a filename and correct MIME type (e.g. `application/pdf`, `image/jpeg`); bare `application/octet-stream` blobs are rejected with 400 "Invalid file type".
197
197
  59a. **MERGED upload workflow tracking** — When `uploadMode: "MERGED"`, the upload response `workflowResourceId` is a **parent** tracking ID. The backend splits the PDF, then creates **child** workflows for each split page — these child IDs appear in `POST /magic/workflows/search` (by fileName or createdAt), NOT the parent ID. To track MERGED progress, search by `fileName` rather than the parent `workflowResourceId`.
198
198
  60. **Response maps transaction types**: Request `INVOICE` → response `SALE`. Request `BILL` → response `PURCHASE`. Request `CUSTOMER_CREDIT_NOTE` → response `SALE_CREDIT_NOTE`. Request `SUPPLIER_CREDIT_NOTE` → response `PURCHASE_CREDIT_NOTE`. S3 paths follow the response type. The response `validFiles[]` array contains `workflowResourceId` for tracking extraction progress via `POST /magic/workflows/search`.
199
199
  61. **Extraction is asynchronous** — the API response is immediate (file upload confirmation only). The actual Magic pipeline — OCR, line item extraction, contact matching, CoA learning, and autofill — runs asynchronously. Use `POST /magic/workflows/search` with `filter.resourceId.eq: "<workflowResourceId>"` to check status (SUBMITTED → PROCESSING → COMPLETED/FAILED). When COMPLETED, `businessTransactionDetails.businessTransactionResourceId` contains the created draft BT ID. The `subscriptionFBPath` in the response is a Firebase Realtime Database path for real-time status updates (alternative to polling).
200
200
  62. **Accepts PDF and JPG/JPEG** — both file types confirmed working. Handwritten documents are accepted at upload stage (extraction quality varies). `fileType` in response reflects actual format: `"PDF"`, `"JPEG"`.
201
- 63. **Workflow search tracks all magic uploads** — `POST /magic/workflows/search` searches across BT extractions AND bank statement imports. Filter by `resourceId` (eq), `documentType` (SALE, PURCHASE, SALE_CREDIT_NOTE, PURCHASE_CREDIT_NOTE, BANK_STATEMENT), `status` (SUBMITTED, PROCESSING, COMPLETED, FAILED), `fileName` (contains), `fileType`, `createdAt` (date range). Response: paginated `MagicWorkflowItem` with `businessTransactionDetails.businessTransactionResourceId` (the draft BT ID when COMPLETED) or `bankStatementDetails` (for bank imports). Standard search sort: `{ sortBy: ["createdAt"], order: "DESC" }`.
201
+ 63. **Workflow search tracks all magic uploads**: `POST /magic/workflows/search` searches across BT extractions AND bank statement imports. Filter by `resourceId` (eq), `documentType` (SALE, PURCHASE, SALE_CREDIT_NOTE, PURCHASE_CREDIT_NOTE, SALE_QUOTE, SALE_ORDER, PURCHASE_REQUEST, PURCHASE_ORDER, BANK_STATEMENT), `status` (SUBMITTED, PROCESSING, COMPLETED, FAILED), `fileName` (contains), `fileType`, `createdAt` (date range). Response: paginated `MagicWorkflowItem` with `businessTransactionDetails.businessTransactionResourceId` (the draft BT ID when COMPLETED) or `bankStatementDetails` (for bank imports). Standard search sort: `{ sortBy: ["createdAt"], order: "DESC" }`.
202
202
 
203
203
  ### Cashflow & Unified Ledger
204
204
  64. **Four ways to read payments — pick by scope.** `GET /payments` (list) and `POST /payments/search` do NOT exist and never did. What does exist: (a) **per-payment CRUD** — `GET/PUT/DELETE /payments/:resourceId`; (b) **payment-scoped search** — `POST /sales/payments/search` and `POST /purchases/payments/search` (added 2026-08-13), one side of the ledger each, plus `POST /batch-payments/search` for batches; (c) **cross-entity ledger** — `POST /cashflow-transactions/search`, the unified transaction ledger spanning invoices, bills, credit notes, journals, cash entries and payments. Filter it by `businessTransactionType` (e.g. `SALE`, `PURCHASE`) and `direction` (`PAYIN`, `PAYOUT`). Response dates are epoch milliseconds. **Naming trap**: the `search_payments` tool is a wrapper over `/cashflow-transactions/search`, NOT over the sales/purchases payment searches — its name is narrower than what it calls. Reach the per-side searches with a raw request; they have no tool. (d) **Per-document settlements** — `GET /invoices/:id/payments` and `GET /bills/:id/payments`, and for credit notes `GET /customer-credit-notes/:id/refunds` / `GET /supplier-credit-notes/:id/refunds` (the domain distinguishes a refund from a payment; a journal has neither). This is the right call for **one known document's own settlements** and the one to reach for first — no filter to get wrong. All four answer `{ data: [...] }` (measured raw 2026-09-07). It is listed here because it was missing from this rule while (c) sat one line away, and `get_transaction_summary` consequently filtered the ledger by `businessTransactionResourceId` — a field `TransactionsFilter` does not declare — for its entire life, 400ing on every call behind a silent catch.
@@ -358,7 +358,7 @@ Bills, invoices, and credit notes share identical mandatory field specs. Adding
358
358
  106. **Contact PUT uses `email` (string), not `emails` (array)** — GET returns `emails: [{email, label}]` (array) but PUT accepts `email: "user@example.com"` (string). Sending the `emails` array in PUT body causes 400 "Invalid request body". The CLI and tool executor handle this automatically via read-modify-write with the correct field.
359
359
 
360
360
  ### Quick Fix (Bulk Update)
361
- 107. **20 Quick Fix endpoints for bulk-updating transactions and line items** — `POST /api/v1/quick-fix/{entity}` with `{ resourceIds: [...], attributes: {...} }`. Only included fields are changed — omitted fields are left unchanged. Response: `{ updated: string[], failed: [{ resourceId, error, errorCode }] }`. **HTTP status codes**: 200 = complete success (`failed` always empty). **207 Multi-Status** = partial or total failure with per-item detail (same response shape as 200 — check `failed` array). 422 = total failure with no per-item breakdown (rare). On 207, retry only `failed` resourceIds. Entities: **ARAP**: invoices, bills, customer-credit-notes, supplier-credit-notes. **Accounting**: journals, cash-entries. **Schedulers**: sale-schedules, purchase-schedules, subscription-schedules, journal-schedules. **Line-item request patterns**: ARAP + accounting use `{ lineItemResourceIds, attributes }`. Schedulers (sale/purchase/subscription) use Pattern C: `{ schedulerUpdates: [{ schedulerResourceId, lineItemUpdates: [{ arrayIndex, ...attrs }] }] }`. **Journal-schedules use Pattern D**: `lineItemResourceId` (UUID) instead of `arrayIndex`. **Field gotchas**: cash entries use `currencySetting` (singular: `{ rateFunctionalToSource, exchangeToken }`), NOT `currencySettings`. Journal schedules have `startDate` in addition to `endDate`/`interval`. Tags: string array, max 50 items, max 50 chars each.
361
+ 107. **24 Quick Fix endpoints for bulk-updating transactions and line items**: `POST /api/v1/quick-fix/{entity}` with `{ resourceIds: [...], attributes: {...} }`. Only included fields are changed; omitted fields are left unchanged. Response: `{ updated: string[], failed: [{ resourceId, error, errorCode }] }`. **HTTP status codes**: 200 = complete success (`failed` always empty). **207 Multi-Status** = partial or total failure with per-item detail (same response shape as 200, so check the `failed` array). 422 = total failure with no per-item breakdown (rare). On 207, retry only `failed` resourceIds. Entities: **ARAP**: invoices, bills, customer-credit-notes, supplier-credit-notes. **Accounting**: journals, cash-entries. **Schedulers**: sale-schedules, purchase-schedules, subscription-schedules, journal-schedules. **Orders (line items only, no transaction-level route)**: sale-orders, sale-quotes, purchase-orders, purchase-requests. **Line-item request patterns**: ARAP, accounting and orders use `{ lineItemResourceIds, attributes }` (purchase side adds `withholdingTax`). **Line-item `discount` and `withholdingTax` use the quick fix shapes, not the create/update ones**: `discount: { rateType: "PERCENTAGE"|"FLAT", rateValue }` (not a bare number) and `withholdingTax: { code, rate, rateType, type, description? }` (code, rate, rateType and type all required), on bills, supplier CNs and purchase orders/requests alike. Schedulers (sale/purchase/subscription) use Pattern C: `{ schedulerUpdates: [{ schedulerResourceId, lineItemUpdates: [{ arrayIndex, ...attrs }] }] }`. **Journal-schedules use Pattern D**: `lineItemResourceId` (UUID) instead of `arrayIndex`. **Field gotchas**: cash entries use `currencySetting` (singular: `{ rateFunctionalToSource, exchangeToken }`), NOT `currencySettings`. Journal schedules have `startDate` in addition to `endDate`/`interval`. Tags: string array, max 50 items, max 50 chars each; on invoices, bills and credit notes they total at most 1000 characters joined with `|`, else 422. **Line-item `classifierConfig`** sets or removes one classifier per entry: set = `{ resourceId, type, printable, selectedClasses }` with at least one class; remove = `{ resourceId, deleted: true }`; classifiers not named stay; `[]` changes nothing. A 207 `failed` entry can carry an empty `resourceId` when the failure matched no record.
362
362
  107a. **Ledger Find & Fix: find and fix (recode) records across types with one filter, preview one change, apply it once.** Use it when a user asks to find & fix, recode, reclassify, retag, re-date or move records to another account across many records or several types. `POST /api/v1/ledger/find-fix/transactions/preview` (sets contact, date, capsule, tags) or `POST /api/v1/ledger/find-fix/line-items/preview` (sets account, classifiers), each with `{ filter, change }`, then `POST /api/v1/ledger/find-fix/apply` with `{ previewId }`; conditions, bodies and every code are in endpoints.md section 17a. `JOURNAL` covers manual and cashflow journals only: transfer and trial-balance journals and cash transfers never match, so their ids come back `NOT_FOUND`. **A filter with no condition besides `types` is a 422, and a condition with no operator is ignored.** **The API refuses a key it does not take, at any level, with 400 `invalid_filter` naming the key**; the tools and the CLI refuse a field of the other level before the request, naming the level that takes it. `tags` `{ add, remove }` keeps the record's other tags, so setting tags to X means removing the current ones and adding X. A classifier removal needs only `{ resourceId, deleted: true }`, even for a classifier the organization no longer has. **Preview** writes nothing, matches at most 500 records, and returns `previewId` (valid 30 minutes; absent when nothing is eligible). **A blocked field is left as it is while the record's other fields still change.** **Apply** is single use and saves the preview-time values, so a field edited between preview and apply, tags included, is overwritten. Once it has taken the preview it runs to the end even if the caller leaves, and starts no new call 3 minutes after the request arrived. 207 lists the `failed` records with an `errorCode`; `OUTCOME_UNKNOWN` means that record may have changed. 404 `PREVIEW_NOT_FOUND` (expired, used, being applied, or another caller's): preview again, never resend. **Any other 5xx, or a timeout, on apply means the outcome is unknown: if the connection drops, the apply keeps running for up to 4 minutes. Wait that long before previewing or applying again on the same records, then preview again or re-read them. Never apply this previewId again.** Several applies can run at the same time. When two applies change records on one document at once, the one saved last can undo the other's changes, including fields and line items it did not set. Preview again to check the result. Lock dates, filed tax periods and claims-backed documents fail per record, and e-invoice filings may be re-submitted. Rule 107's per-type routes stay for one document, for fields this does not change (due date, tax profile, notes, amounts, custom fields) and for scheduled transactions.
363
363
 
364
364
  ### Transfer Trial Balance
@@ -1141,6 +1141,14 @@ Processing is **asynchronous** — the API response confirms file upload immedia
1141
1141
  - `BILL` → creates a draft purchase (response type: `PURCHASE`)
1142
1142
  - `CUSTOMER_CREDIT_NOTE` → creates a draft customer CN (response type: `SALE_CREDIT_NOTE`)
1143
1143
  - `SUPPLIER_CREDIT_NOTE` → creates a draft supplier CN (response type: `PURCHASE_CREDIT_NOTE`)
1144
+ - `SALE_QUOTE` → creates a DRAFT sale quote (response type: `SALE_QUOTE`); issue it with `isDraftToActiveSaleQuote`
1145
+ - `SALE_ORDER` → creates a PENDING sale order (response type: `SALE_ORDER`); take it live with `isPendingToActiveSaleOrder`
1146
+ - `PURCHASE_REQUEST` → creates a DRAFT purchase request (response type: `PURCHASE_REQUEST`); issue it with `isDraftToActivePurchaseRequest`
1147
+ - `PURCHASE_ORDER` → creates a PENDING purchase order (response type: `PURCHASE_ORDER`); take it live with `isPendingToActivePurchaseOrder`
1148
+
1149
+ A PENDING order is on the dashboard's For Review tab, not in the live order lists. Activate it with the order update (`PUT /sale-orders/:id` / `PUT /purchase-orders/:id`); if that call sends `lineItems`, send every stored line with its `resourceId`.
1150
+
1151
+ Optional `internalNotes` (max 3000 characters) is set on the created record, e.g. a tag to find an automated upload again. Optional `uploadMode: "MERGED"` splits one PDF into several documents; it is refused (`MAGIC_MERGED_UPLOAD_NOT_SUPPORTED`) for the four quote/order/request types.
1144
1152
 
1145
1153
  **Three modes** — content type depends on `sourceType`:
1146
1154
 
@@ -1152,8 +1160,9 @@ Content-Type: multipart/form-data
1152
1160
 
1153
1161
  Fields:
1154
1162
  - sourceFile: PDF or JPG file blob (NOT "file")
1155
- - businessTransactionType: "INVOICE", "BILL", "CUSTOMER_CREDIT_NOTE", or "SUPPLIER_CREDIT_NOTE"
1163
+ - businessTransactionType: "INVOICE", "BILL", "CUSTOMER_CREDIT_NOTE", "SUPPLIER_CREDIT_NOTE", "SALE_QUOTE", "SALE_ORDER", "PURCHASE_REQUEST", or "PURCHASE_ORDER"
1156
1164
  - sourceType: "FILE"
1165
+ - internalNotes: optional, max 3000 characters
1157
1166
  ```
1158
1167
 
1159
1168
  ```json
@@ -1230,13 +1239,14 @@ Content-Type: application/json
1230
1239
 
1231
1240
  **Key gotchas:**
1232
1241
  - `sourceFile` is the field name (NOT `file`) — same pattern as bank statement endpoint
1233
- - `EXPENSE` returns 422 — use one of the 4 valid types above
1234
- - Response maps types: `INVOICE` → `SALE`, `BILL` → `PURCHASE`, `CUSTOMER_CREDIT_NOTE` → `SALE_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE` → `PURCHASE_CREDIT_NOTE`
1242
+ - `EXPENSE` returns 422: use one of the 8 valid types above
1243
+ - Response maps types: `INVOICE` → `SALE`, `BILL` → `PURCHASE`, `CUSTOMER_CREDIT_NOTE` → `SALE_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE` → `PURCHASE_CREDIT_NOTE`; the four quote/order/request types keep their names
1244
+ - There is no attachment-id source: the sources are `sourceFile`, `sourceURL` and `html` only
1235
1245
  - JSON body with `sourceType: "FILE"` always fails (400) — MUST use multipart
1236
1246
  - `workflowResourceId` in `validFiles[]` is for tracking via `POST /magic/workflows/search`
1237
1247
  - `subscriptionFBPath` is the Firebase path for real-time status updates
1238
1248
  - All three fields (the source — `sourceFile`/`sourceURL`/`html` — plus `businessTransactionType` and `sourceType`) are required — omitting any returns 422
1239
- - File types confirmed: PDF, JPG/JPEG, PNG, HEIC, XLS, XLSX, EML (max 1 MB). HTML mode (`sourceType: "HTML"`) takes the raw HTML body instead of a file (max 5 MB); an `.eml` file is still FILE mode, not HTML mode.
1249
+ - File types confirmed: PDF, JPG/JPEG, PNG, HEIC, XLS, XLSX, EML (max 10 MB). HTML mode (`sourceType: "HTML"`) takes the raw HTML body instead of a file (max 5 MB); an `.eml` file is still FILE mode, not HTML mode.
1240
1250
 
1241
1251
  ---
1242
1252
 
@@ -1287,7 +1297,7 @@ Content-Type: application/json
1287
1297
 
1288
1298
  **Filter fields:**
1289
1299
  - `resourceId`: StringExpression (eq, contains) — workflow ID from magic create response
1290
- - `documentType`: Array — SALE, PURCHASE, SALE_CREDIT_NOTE, PURCHASE_CREDIT_NOTE, BANK_STATEMENT
1300
+ - `documentType`: Array: SALE, PURCHASE, SALE_CREDIT_NOTE, PURCHASE_CREDIT_NOTE, SALE_QUOTE, SALE_ORDER, PURCHASE_REQUEST, PURCHASE_ORDER, BANK_STATEMENT
1291
1301
  - `status`: Array — SUBMITTED, PROCESSING, COMPLETED, FAILED
1292
1302
  - `fileName`: StringExpression — original uploaded filename
1293
1303
  - `fileType`: Array — PDF, PNG, JPEG, JPG, HEIC, CSV, XLS, XLSX, EML
@@ -1297,7 +1307,7 @@ Content-Type: application/json
1297
1307
  1. Upload via `POST /magic/createBusinessTransactionFromAttachment` → get `workflowResourceId`
1298
1308
  2. Search with `filter.resourceId.eq` → check `status`
1299
1309
  3. When `COMPLETED` → read `businessTransactionDetails.businessTransactionResourceId`
1300
- 4. Use the BT resource ID with `GET /invoices/:id`, `GET /bills/:id`, `GET /customer-credit-notes/:id`, or `GET /supplier-credit-notes/:id`
1310
+ 4. Use the BT resource ID with `GET /invoices/:id`, `GET /bills/:id`, `GET /customer-credit-notes/:id`, `GET /supplier-credit-notes/:id`, or the matching quote/order/request GET
1301
1311
 
1302
1312
 
1303
1313
  ---
@@ -1319,6 +1329,8 @@ Fields:
1319
1329
  - sourceType: "FILE" (valid values: URL, FILE)
1320
1330
  ```
1321
1331
 
1332
+ Max 10 MB per file. There is no attachment-id source.
1333
+
1322
1334
  CSV format: `Date,Description,Debit,Credit` — maps to Date, Description, Cash-out, Cash-in.
1323
1335
 
1324
1336
  Multipart import is the more reliable method. Use it when JSON POST returns errors.
@@ -1925,7 +1937,7 @@ Middleware on payment, credit, and refund endpoints automatically wraps a flat J
1925
1937
 
1926
1938
  ## 17. Quick Fix (Bulk Update)
1927
1939
 
1928
- 20 endpoints for bulk-updating transactions and line items in a single API call.
1940
+ 24 endpoints for bulk-updating transactions and line items in a single API call: 10 entities with both routes, plus 4 order entities with a line-items route only.
1929
1941
 
1930
1942
  ### Pattern
1931
1943
 
@@ -1939,6 +1951,7 @@ POST /api/v1/quick-fix/{entity}/line-items
1939
1951
  **ARAP**: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`
1940
1952
  **Accounting**: `journals`, `cash-entries`
1941
1953
  **Schedulers**: `sale-schedules`, `purchase-schedules`, `subscription-schedules`, `journal-schedules`
1954
+ **Orders (line items only)**: `sale-orders`, `sale-quotes`, `purchase-orders`, `purchase-requests`. There is no `POST /api/v1/quick-fix/{order-entity}` route.
1942
1955
 
1943
1956
  ### Transaction-Level Request
1944
1957
 
@@ -1955,7 +1968,7 @@ POST /api/v1/quick-fix/bills
1955
1968
  }
1956
1969
  ```
1957
1970
 
1958
- ### Line-Item-Level Request (ARAP + Accounting)
1971
+ ### Line-Item-Level Request (ARAP, Accounting, Orders)
1959
1972
 
1960
1973
  ```json
1961
1974
  POST /api/v1/quick-fix/invoices/line-items
@@ -1987,9 +2000,9 @@ POST /api/v1/quick-fix/sale-schedules/line-items
1987
2000
  }
1988
2001
  ```
1989
2002
 
1990
- ### Response (all 20 endpoints)
2003
+ ### Response (all 24 endpoints)
1991
2004
 
1992
- **HTTP status codes**: 200 = complete success (`failed` always `[]`). **207 Multi-Status** = partial or total failure with per-item detail (same body shape as 200). 422/500 = total failure, standard error shape (no per-item data). On 207, retry only `failed` resourceIds — `updated` ones are done.
2005
+ **HTTP status codes**: 200 = complete success (`failed` always `[]`). **207 Multi-Status** = partial or total failure with per-item detail (same body shape as 200). 422/500 = total failure, standard error shape (no per-item data). On 207, retry only `failed` resourceIds (`updated` ones are done). A `failed` entry's `resourceId` is empty when the failure could not be matched to a record.
1993
2006
 
1994
2007
  ```json
1995
2008
  {
@@ -2015,7 +2028,16 @@ Only included fields are changed — omitted fields are left unchanged.
2015
2028
  - **Purchase schedules**: endDate, interval, contactResourceId, currencySettings, taxCurrencySettings, tags, customFields, capsuleResourceId
2016
2029
  - **Journal schedules**: startDate, endDate, interval, contactResourceId, tags, internalNotes, capsuleResourceId
2017
2030
 
2018
- **Line items — ARAP (Pattern B)**: name, quantity, unit, unitPrice, discount, itemResourceId, organizationAccountResourceId, taxProfileResourceId, classifierConfig, withholdingTax (bills/supplier-CNs only).
2031
+ **Line items, ARAP and orders (Pattern B)**: name, quantity, unit, unitPrice, discount, itemResourceId, organizationAccountResourceId, taxProfileResourceId, classifierConfig, withholdingTax (purchase side only: bills, supplier CNs, purchase orders, purchase requests).
2032
+
2033
+ **Quick fix line-item shapes differ from create/update** (every Pattern B route, orders included):
2034
+
2035
+ | Field | Quick fix shape | Create / update shape |
2036
+ |-------|-----------------|-----------------------|
2037
+ | `discount` | `{ "rateType": "PERCENTAGE" \| "FLAT", "rateValue": 10 }` (rateValue ≥ 0; a percentage is 0-100) | a number |
2038
+ | `withholdingTax` | `{ "code", "rate", "rateType", "type", "description"? }`: code, rate, rateType and type required | `{ "code", "rate" }` |
2039
+
2040
+ **Line item `classifierConfig`** (every line-item route): each entry sets or removes ONE classifier; classifiers the request does not name are left as they are, and `[]` changes nothing. Set: `{ resourceId, type, printable, selectedClasses }` with at least one class. Remove: `{ resourceId, deleted: true }` (type, printable and selectedClasses not needed). Each selected class needs `className` plus `resourceId`, or `entityResourceId` instead when the classifier draws its options from customers, suppliers, contacts, employees or users.
2019
2041
 
2020
2042
  **Line items — journal/cash-entry (Pattern B)**: organizationAccountResourceId, amount, description, taxProfileResourceId, classifierConfig.
2021
2043
 
@@ -2045,7 +2067,7 @@ POST /api/v1/quick-fix/journal-schedules/line-items
2045
2067
 
2046
2068
  Note: journal-schedules use `lineItemResourceId` (UUID), NOT `arrayIndex`.
2047
2069
 
2048
- **Tags**: string array, max 50 items, max 50 chars each.
2070
+ **Tags**: string array, max 50 items, max 50 chars each. On invoices, bills and both credit notes the tags, joined with `|`, total at most 1000 characters, else 422.
2049
2071
 
2050
2072
  ---
2051
2073
 
@@ -2057,7 +2079,7 @@ Find and fix (recode) records across invoices, bills, both credit notes, journal
2057
2079
  |------------------|-----------|
2058
2080
  | `types` (required) | `INVOICE`, `BILL`, `CUSTOMER_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE`, `JOURNAL` (manual and cashflow journals only), `CASH_ENTRY` |
2059
2081
  | `resourceIds` | Up to 500; line item ids at line level |
2060
- | `reference` | `eq`, `in`, `contains`, `startWith` |
2082
+ | `reference` | `eq`, `in` (up to 100 values, as for every `in`), `contains`, `startWith` |
2061
2083
  | `valueDate` | `eq`, `gte`, `lte`, `between: [from, to]` |
2062
2084
  | `contactResourceId` | `eq`, `in` |
2063
2085
  | `organizationAccountResourceId` | `eq`, `in`; line level only |
@@ -2133,6 +2155,7 @@ A blocked field is left as it is while the record's other fields still change, a
2133
2155
  | `FOREIGN_CURRENCY_VALUE_DATE` | date | A new date on a foreign currency record would take a new exchange rate |
2134
2156
  | `VALUE_DATE_AFTER_DUE_DATE` | date | The new date is after the document's due date |
2135
2157
  | `TOO_MANY_TAGS` | tags | The record would end with more than 50 tags |
2158
+ | `TAGS_TOO_LONG` | tags | Invoices, bills and credit notes: the record's tags, joined with `\|`, would total more than 1000 characters |
2136
2159
  | `CONTROL_LINE` | account | A journal line on a bank, cash or control account |
2137
2160
 
2138
2161
  ### POST /api/v1/ledger/find-fix/apply
@@ -2168,7 +2191,7 @@ Several applies can run at the same time. When two applies change records on one
2168
2191
  | 422 | `CLASSIFIER_NOT_FOUND`, `CLASS_NOT_FOUND` | Line items preview, set entries only: a classifier the change sets does not exist, or a class it selects is not a current class of that classifier; `resourceId` names the classifier or class. A removal and a record-list selection (`entityResourceId`) are not checked |
2169
2192
  | 422 | `TOO_MANY_RECORDS` | Either preview: at least `count` records or line items match, more than `limit` |
2170
2193
  | 422 | `TOO_MANY_CALLS` | Transactions preview: the change needs `count` separate updates, more than `limit`, because records whose resulting values differ need separate updates. A line items preview never answers it |
2171
- | 503 | `PREVIEW_STORE_UNAVAILABLE` | Nothing applied |
2194
+ | 503 | `PREVIEW_STORE_UNAVAILABLE` | On apply: nothing applied, and the preview may be used up (preview again if a retry answers `PREVIEW_NOT_FOUND`). On preview: no previewId was issued; run the preview again |
2172
2195
 
2173
2196
  Any other 5xx, or a timeout, on apply: the outcome is unknown. If the connection drops, apply keeps running for up to 4 minutes. Wait that long before previewing or applying again on the same records, then preview again or re-read them. Never apply this previewId again. A service restart can stop an apply; preview again to check.
2174
2197
 
@@ -635,14 +635,13 @@ account. Full model: SKILL.md Rule 47a, `endpoints.md` → Deposits, `feature-gl
635
635
  **Note**: This is the same class as the inventory-adjustment endpoints — the thing being reached for does not exist at any spelling, so re-spelling never helps. Four consecutive re-tries of the same path in different shapes is the signature.
636
636
  **Fix**: Pick a route that actually delivers the bytes or a reachable address:
637
637
  - **FILE mode** — send the bytes yourself: `sourceType: "FILE"` with a `sourceFile` multipart blob (see Rule 58/59).
638
- - **attachmentId** — upload in the Jaz dashboard first, then reference it.
639
638
  - **Share link** — Dropbox / Google Drive / OneDrive, or any public https URL.
640
639
  - **Attach it to the conversation** — on MCP surfaces the host then populates `file` itself. Never author that object by hand.
641
640
  - **Local folder or `.zip`** — valid for `classify_documents` ONLY when the client is running on the caller's own machine, not on a hosted server.
642
641
 
643
642
  ### "The file reference has no fetchable https download_url"
644
643
  **Cause**: A `file` object was constructed by the caller rather than supplied by the host, usually with a sandbox path in `download_url`.
645
- **Fix**: Omit `file` entirely when the user attached nothing, and pass `sourceUrl` or `attachmentId` instead. `file` is host-populated; there is no way to synthesize one.
644
+ **Fix**: Omit `file` entirely when the user attached nothing, and pass `sourceUrl` instead (the Magic uploads have no attachment-id source). `file` is host-populated; there is no way to synthesize one.
646
645
 
647
646
  ---
648
647
 
@@ -251,9 +251,9 @@ Bank statement import supports CSV and PDF with configurable column mapping. Sta
251
251
 
252
252
  ### Quick Fix (Bulk Update)
253
253
 
254
- Mass-edit transactions and line items in a single operation. Replaces the need to open and update each transaction individually. Supports all transaction types (invoices, bills, credit notes, journals, cash entries) and their scheduled/subscription variants. Common use cases: batch date corrections, reassigning contacts, bulk-tagging for reporting, changing accounts/tax profiles across multiple line items.
254
+ Mass-edit transactions and line items in a single operation. Replaces the need to open and update each transaction individually. Supports all transaction types (invoices, bills, credit notes, journals, cash entries) and their scheduled/subscription variants, plus line items on sale orders, sale quotes, purchase orders and purchase requests. Common use cases: batch date corrections, reassigning contacts, bulk-tagging for reporting, changing accounts/tax profiles across multiple line items.
255
255
 
256
- **API**: `POST /api/v1/quick-fix/{entity}` (transaction-level) + `POST /api/v1/quick-fix/{entity}/line-items` (line-item-level). 20 endpoints total.
256
+ **API**: `POST /api/v1/quick-fix/{entity}` (transaction-level) + `POST /api/v1/quick-fix/{entity}/line-items` (line-item-level). 24 endpoints total (orders: line items only).
257
257
 
258
258
  ### Ledger Find & Fix
259
259
 
@@ -448,8 +448,8 @@ Body for all three: `{ items: [{btResourceId: "<uuid>", btType: "SALE|PURCHASE|S
448
448
 
449
449
  | Method | Path | Description |
450
450
  |--------|------|-------------|
451
- | POST | `/magic/createBusinessTransactionFromAttachment` | **Jaz Magic: Extraction & Autofill.** Upload PDF/JPG → full extraction pipeline (OCR, line items, contact matching, CoA ML learning) → draft transaction with all fields autofilled. Supports `INVOICE`, `BILL`, `CUSTOMER_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE`. FILE mode = multipart (`sourceFile` blob), URL mode = JSON (`sourceURL`). Async — returns `workflowResourceId` for tracking via workflow search. Request maps: `INVOICE`→`SALE`, `BILL`→`PURCHASE`, `CUSTOMER_CREDIT_NOTE`→`SALE_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE`→`PURCHASE_CREDIT_NOTE`. |
452
- | POST | `/magic/workflows/search` | **Workflow search.** Track magic upload status across BT extractions and bank imports. Filter by `resourceId`, `documentType` (SALE/PURCHASE/SALE_CREDIT_NOTE/PURCHASE_CREDIT_NOTE/BANK_STATEMENT), `status` (SUBMITTED/PROCESSING/COMPLETED/FAILED), `fileName`, `fileType`, `createdAt`. Response includes `businessTransactionDetails.businessTransactionResourceId` (the draft BT ID) when COMPLETED. |
451
+ | POST | `/magic/createBusinessTransactionFromAttachment` | **Jaz Magic: Extraction & Autofill.** Upload PDF/JPG → full extraction pipeline (OCR, line items, contact matching, CoA ML learning) → draft transaction with all fields autofilled. Supports `INVOICE`, `BILL`, `CUSTOMER_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE`, `SALE_QUOTE`, `SALE_ORDER`, `PURCHASE_REQUEST`, `PURCHASE_ORDER` (orders land PENDING). Max 10 MB; optional `internalNotes` (max 3000). FILE mode = multipart (`sourceFile` blob), URL mode = JSON (`sourceURL`). Async: returns `workflowResourceId` for tracking via workflow search. Request maps: `INVOICE`→`SALE`, `BILL`→`PURCHASE`, `CUSTOMER_CREDIT_NOTE`→`SALE_CREDIT_NOTE`, `SUPPLIER_CREDIT_NOTE`→`PURCHASE_CREDIT_NOTE`. |
452
+ | POST | `/magic/workflows/search` | **Workflow search.** Track magic upload status across BT extractions and bank imports. Filter by `resourceId`, `documentType` (SALE/PURCHASE/SALE_CREDIT_NOTE/PURCHASE_CREDIT_NOTE/SALE_QUOTE/SALE_ORDER/PURCHASE_REQUEST/PURCHASE_ORDER/BANK_STATEMENT), `status` (SUBMITTED/PROCESSING/COMPLETED/FAILED), `fileName`, `fileType`, `createdAt`. Response includes `businessTransactionDetails.businessTransactionResourceId` (the draft BT ID) when COMPLETED. |
453
453
  | POST | `/magic/importBankStatementFromAttachment` | Convert bank statement → entries |
454
454
 
455
455
  ---
@@ -733,13 +733,14 @@ These features exist in the Jaz platform and may affect API responses or cause u
733
733
  - Move transactions between capsules via `POST /api/v1/moveTransactionCapsules`
734
734
  - Search transactions within capsules
735
735
 
736
- ### Quick Fix (Bulk Update) — 20 Endpoints
736
+ ### Quick Fix (Bulk Update): 24 Endpoints
737
737
 
738
738
  Bulk-update transactions or line items in a single call. Pattern: `POST /api/v1/quick-fix/{entity}` + `POST /api/v1/quick-fix/{entity}/line-items`.
739
739
 
740
740
  **ARAP**: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes` (× 2 = 8)
741
741
  **Accounting**: `journals`, `cash-entries` (× 2 = 4)
742
742
  **Schedulers**: `sale-schedules`, `purchase-schedules`, `subscription-schedules`, `journal-schedules` (× 2 = 8)
743
+ **Orders**: `sale-orders`, `sale-quotes`, `purchase-orders`, `purchase-requests` (line items only = 4)
743
744
 
744
745
  Request: `{ resourceIds: [...], attributes: {...} }` (transactions) or `{ lineItemResourceIds: [...], attributes: {...} }` (line items) or `{ schedulerUpdates: [...] }` (scheduler line items).
745
746
  Response: `{ updated: [...], failed: [{ resourceId, error, errorCode }] }`. HTTP 200 = all succeeded. **207 Multi-Status** = partial failure (check both arrays). 422/500 = total failure (standard error shape).
@@ -81,6 +81,8 @@ To change lines:
81
81
 
82
82
  The update tools (and `clio … update --lines`) pre-flight this against the stored document: lines with no `resourceId` at all on a document that already has lines are refused locally (nothing is written) unless `appendLines: true` (CLI `--append-lines`) says adding is the intent; naming some stored lines but not all is refused locally with the missing ids.
83
83
 
84
+ To change a few fields on some lines without resending the document, use `quick_fix_line_items` (`clio quick-fix <entity> --line-items`) with entity `sale-orders`, `sale-quotes`, `purchase-orders` or `purchase-requests`: `{ lineItemResourceIds, attributes }`, only the fields sent change, and the lines not named are untouched. Attributes: name, quantity, unit, unitPrice, discount, itemResourceId, organizationAccountResourceId, taxProfileResourceId, classifierConfig, plus withholdingTax on purchase orders and requests. `discount` and `withholdingTax` take the quick fix shapes, not the ones this page's create/update use (`discount: { rateType, rateValue }`, `withholdingTax: { code, rate, rateType, type }`): see endpoints.md section 17. Orders have line-item quick fix only: `quick_fix_transactions` refuses them.
85
+
84
86
  ## Delete vs Void
85
87
 
86
88
  - **DELETE is draft-only** (422 on anything non-draft). `transition_* action:DELETE` pre-flights status and returns a `repair` hint to use `VOID` for non-draft records.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-cli
3
- version: 5.67.0
3
+ version: 5.69.0
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,
@@ -535,11 +535,11 @@ Also: `clio reports pdf` — generate PDF from a message/document.
535
535
  ### `clio magic` — AI document extraction
536
536
  | Subcommand | Key flags |
537
537
  |------------|-----------|
538
- | `create` | one of `--file <path>` / `--url <url>` / `--html <string\|@file>`; `--type` (invoice, bill, credit-note-customer, credit-note-supplier); `--merged` (split a multi-doc PDF). `--html` takes raw HTML (e.g. an email body), rendered to a PDF server-side. Encrypted PDFs: `name__pw__password.pdf`. |
538
+ | `create` | one of `--file <path>` / `--url <url>` / `--html <string\|@file>`; `--type` (invoice, bill, credit-note-customer, credit-note-supplier, sale-quote, sale-order, purchase-request, purchase-order); `--merged` (split a multi-doc PDF; not for quotes/orders/requests); `--internal-notes` (max 3000). Max 10 MB per file. `--html` takes raw HTML (e.g. an email body), rendered to a PDF server-side. Encrypted PDFs: `name__pw__password.pdf`. |
539
539
  | `status <workflowIds>` | Comma-separated workflow IDs |
540
540
 
541
541
  ### `clio quick-fix <entity>` — Bulk-update transactions
542
- Entities: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `journals`, `cash-entries`, `sale-schedules`, `purchase-schedules`, `subscription-schedules`, `journal-schedules`
542
+ Entities: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `journals`, `cash-entries`, `sale-schedules`, `purchase-schedules`, `subscription-schedules`, `journal-schedules`, and with `--line-items` only: `sale-orders`, `sale-quotes`, `purchase-orders`, `purchase-requests`
543
543
 
544
544
  | Flag | Purpose |
545
545
  |------|---------|
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-conversion
3
- version: 5.67.0
3
+ version: 5.69.0
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.67.0
3
+ version: 5.69.0
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.67.0
3
+ version: 5.69.0
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.67.0
3
+ version: 5.69.0
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,
@@ -7,7 +7,7 @@
7
7
  ### Platform tools
8
8
  - **`mcp magic create --file <pdf>` / `create_bt_from_attachment(businessTransactionType: 'BILL'|'INVOICE'|'CUSTOMER_CREDIT_NOTE'|'SUPPLIER_CREDIT_NOTE', sourceUrl)`** — step 4: OCR + line-item extraction + contact + CoA suggestion. Creates DRAFT transaction.
9
9
  - **`finalize_bill(...)` / `finalize_invoice(...)` / `finalize_customer_credit_note(...)`** — step 5: finalize practitioner-reviewed Magic-extracted DRAFTs.
10
- - **`import_bank_statement(accountResourceId, sourceUrl | attachmentId)`** — step 6: bank statements (CSV / OFX / PDF); creates bank records pending reconciliation per `bank-recon.md`.
10
+ - **`import_bank_statement(accountResourceId, sourceUrl | attached file)`**: step 6: bank statements (CSV / OFX / PDF); creates bank records pending reconciliation per `bank-recon.md`.
11
11
  - **`search_background_jobs(filter: {resourceId: {eq: <jobId>}})`** — step 7: poll Magic / bank-import async jobs to terminal status.
12
12
 
13
13
  ### CLI tools (jaz-cli — offline)
@@ -133,7 +133,7 @@ Match by name + currency to the statement (typically the bank logo + account num
133
133
  ```
134
134
  import_bank_statement(
135
135
  accountResourceId: <bank id>,
136
- sourceUrl: <statement file URL> // or attachmentId
136
+ sourceUrl: <statement file URL> // or a file attached to the call (max 10 MB)
137
137
  )
138
138
  ```
139
139
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-recipes
3
- version: 5.67.0
3
+ version: 5.69.0
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