jaz-clio 5.47.1 → 5.47.3

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.47.1
3
+ version: 5.47.3
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
@@ -129,9 +129,9 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
129
129
  34. **Bookmarks use `items` array wrapper** with `name`, `value`, `categoryCode`, `datatypeCode`.
130
130
 
131
131
  ### Custom Fields
132
- 35. **Do NOT send `appliesTo` on custom field POST** — causes "Invalid request body". Only send `name`, `type`, `printOnDocuments`.
132
+ 35. **Custom fields: `appliesTo` WORKS and `type` does nothing** (re-probed live 2026-09-02, reversing the previous entry). Send `appliesTo` as an OBJECT `{invoices, bills, customerCredits, supplierCredits, payments}` sets the matching `applyTo*` to `SHOW`; **omit it and the field appears on nothing**. The old "do not send appliesTo" note came from an ARRAY example, which does 400. `format` is the ONLY control over the kind of field and the datatype is derived, not chosen: `CUSTOM` (default) yields `datatypeCode: TEXT`, any `ALL_*` value (`ALL_CUSTOMERS`/`ALL_SUPPLIERS`/`ALL_CONTACTS`/`ALL_EMPLOYEES`/`ALL_USERS`) yields `LIST`, a picklist of that population. **There is no NUMBER, DATE or DROPDOWN custom field**: `type`, `fieldType`, `entityType`, `datatypeCode` and `options` all return 200 and are silently dropped (an int on `datatypeCode` also returns 200, so the DTO does not declare it). `printOnDocuments` is required and not defaulted server-side.
133
133
  35a. **Custom field values on transactions**: Set via `customFields: [{ customFieldName: "PO Number", actualValue: "PO-123" }]` on invoice/bill/customer-CN/supplier-CN/payment/item/fixed-asset create/update. NOT on journals, cash entries, or cash transfers. Read from GET responses in the same shape.
134
- 35b. **Custom field search**: `POST /custom-fields/search` with filter/sort/limit/offset. Filter by `customFieldName` (StringExpression), `datatypeCode` (StringExpression: TEXT, DATE, DROPDOWN).
134
+ 35b. **Custom field search**: `POST /custom-fields/search` with filter/sort/limit/offset. Filter by `customFieldName` (StringExpression), `datatypeCode` (StringExpression: TEXT, LIST, DATE — there is no DROPDOWN; see rule 35).
135
135
  35c. **Custom field GET**: `GET /custom-fields/:resourceId` returns full definition including `applyToSales`, `applyToPurchase`, `applyToCreditNote`, `applyToPayment`, `printOnDocuments`, `listOptions`.
136
136
 
137
137
  ### Tags on Transactions
@@ -171,7 +171,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
171
171
  43. **Search sort is an object** — `{ sort: { sortBy: ["valueDate"], order: "DESC" } }`. Required when `offset` is present (even `offset: 0`).
172
172
  44. **Bank records** — **Create**: Multipart CSV/OFX via `POST /magic/importBankStatementFromAttachment` or JSON via `POST /bank-records/:accountResourceId` with `{ records: [{amount, transactionDate, description?, payerOrPayee?, reference?}] }` (positive = cash-in, negative = cash-out, response: `{data: {errors: []}}`). **Search**: `POST /bank-records/:accountResourceId/search` — filter fields: `valueDate` (DateExpression), `status` (StringExpression: UNRECONCILED, RECONCILED, ARCHIVED, POSSIBLE_DUPLICATE), `description`, `extContactName` (payer/payee), `extReference`, `netAmount` (BigDecimalExpression), `extAccountNumber`. Sort by `valueDate` DESC default.
173
173
  45. **Withholding tax** on bills/supplier CNs only. Retry pattern: if `WITHHOLDING_CODE_NOT_FOUND`, strip field and retry.
174
- 46. **Known API bugs (500s)**: Contact groups PUT (nil pointer on search response), custom fields PUT (dangling stack pointers in mapping), capsules POST (upstream returns nil), catalogs POST, inventory balances by status GET (`/inventory-balances/:status`, missing `c.Bind`) — all return 500.
174
+ 46. **Known API bugs (500s)**: capsules POST (upstream returns nil), catalogs POST, inventory balances by status GET (`/inventory-balances/:status`, missing `c.Bind`). **Contact groups PUT and custom fields PUT are NO LONGER on this list** both were re-probed live 2026-09-02 and returned 200 and applied the change. Do not route around them.
175
175
  47. **Non-existent endpoints**: `POST /inventory/adjustments` (and `/inventory-adjustments`, `/inventory-items/:id/adjustments`, `/items/:id/inventory-adjustments` — no stock-adjustment write path exists at any spelling), `GET /payments` (list), and `POST /payments/search` return 404 — these endpoints are not implemented. For payments, per-payment CRUD is `GET/PUT/DELETE /payments/:resourceId` and there ARE two payment-scoped searches — see Rule 64. `POST /deposits` also 404s, but for a different reason — see Rule 47a; do not read it as a missing feature.
176
176
  47a. **Deposits are not an entity — the 404 on `/deposits` is by design.** A deposit is a **flag on a Chart of Accounts account**, not a document: the account carries `depositContactType` = `CUSTOMER` (advance received, a liability) or `SUPPLIER` (advance paid, an asset). Once flagged, a deposit movement is an **ordinary transaction against that account** — top up with `POST /journals` / `POST /cash-in-entries` / `POST /cash-out-entries` (one leg on the flagged account), draw down with `POST /invoices/:id/payments` or `POST /bills/:id/payments` passing `accountResourceId` = the flagged account **and `paymentMethod` set to something other than BANK_TRANSFER / CASH / CHEQUE** (use `OTHER`) — those three force a bank/cash account and 422 here, see Rule 80, read with `POST /cashflow-transactions/search`. **Flagging the account is a web-app action**: `depositContactType` is on no chart-of-accounts request or response model here, and the platform-backend mutation that sets it (`configureDepositAccounts`) is not proxied — so `POST /chart-of-accounts` cannot create a deposit account. Over the API you can only read and post against an account someone already flagged. Full walkthrough: `references/endpoints.md` → Deposits.
177
177
  48. **Attachments — full CRUD**: **Add**: `POST /:type/:id/attachments` (multipart, `file` field, `application/pdf` or `image/*` — NOT `text/plain`). **List**: `GET /:type/:id/attachments`. **Delete**: `DELETE /:type/:id/attachments/:attachmentResourceId` (HTTP 200). CLI: `clio attachments add --file <path>` or `--url <url>`, `clio attachments list`, `clio attachments delete <attachmentResourceId>`. **Response shape is non-standard**: `{ reference, resourceId, attachments: [{fileName, fileType, fileId, attachmentResourceId}] }` — NOT `{ data: [...] }`. The attachment ID field is `attachmentResourceId` (not `resourceId`).
@@ -866,26 +866,23 @@ Always wrap in `{ payments: [...] }` even for single payment.
866
866
  ### POST /api/v1/custom-fields
867
867
 
868
868
  ```json
869
- // Request (TEXT type):
870
- { "name": "PO Number", "type": "TEXT", "printOnDocuments": false }
869
+ // Request (free-text field on invoices and bills):
870
+ { "name": "PO Number", "printOnDocuments": false, "appliesTo": { "invoices": true, "bills": true } }
871
871
 
872
- // Request (DROPDOWN type with options):
873
- { "name": "Priority", "type": "DROPDOWN", "printOnDocuments": false, "options": ["Low", "Medium", "High"] }
872
+ // Request (picklist of every customer):
873
+ { "name": "Account Manager", "printOnDocuments": false, "format": "ALL_CUSTOMERS", "appliesTo": { "invoices": true } }
874
874
 
875
- // Request (DATE type):
876
- { "name": "Delivery Date", "type": "DATE", "printOnDocuments": true }
877
-
878
- // Response (includes both canonical and alias names):
875
+ // Response:
879
876
  { "data": { "customFieldName": "PO Number", "name": "PO Number", "status": "ACTIVE", "resourceId": "uuid" } }
880
877
  ```
881
878
 
882
- **CRITICAL notes from live testing**:
879
+ **CRITICAL notes re-probed live 2026-09-02, correcting several earlier entries**:
880
+ - **PUT works.** The 500 this file and SKILL.md rule 46 recorded is gone: a PUT returned 200 and applied the change. But it is a FULL REPLACE of `appliesTo` + `printOnDocuments`, and the GET returns `printOnDocuments` as null — the truth is in the `applyTo*` enum, where `PRINT` means it prints and `SHOW` means it does not. `updateCustomField` hydrates from that enum; a raw caller that omits `printOnDocuments` will silently turn printing off.
883
881
  - POST uses `name`, GET returns both `customFieldName` and `name`
884
- - Valid `type` values: `"TEXT"`, `"DATE"`, `"DROPDOWN"` (UPPERCASE)
885
- - `printOnDocuments` is REQUIRED and is not defaulted server-side omitting it returns 422 `printOnDocuments is a required field` (probed 2026-09-02; recorded as a 400 before that). `create_custom_field` sends `false` when you omit it.
886
- - Do NOT send `appliesTo` field causes "Invalid request body"
887
- - Only send: `name`, `type`, `printOnDocuments` (and `options` for DROPDOWN)
888
- - For DROPDOWN type, `options` array works (without `appliesTo`)
882
+ - `printOnDocuments` is REQUIRED and is not defaulted server-side — omitting it returns 422 `printOnDocuments is a required field` (recorded as a 400 before that). `create_custom_field` sends `false` when you omit it.
883
+ - **`appliesTo` WORKS and you should send it.** `{ invoices, bills, customerCredits, supplierCredits, payments }` sets the matching `applyTo*` response fields to `SHOW`. Omit it and every one stays `NULL`, i.e. the field appears on nothing. The previous "do NOT send appliesTo, causes Invalid request body" entry is wrong.
884
+ - **`format` is the only control over the KIND of field**, and the datatype is derived from it, not chosen: `CUSTOM` (default) yields `datatypeCode: TEXT`; any `ALL_*` value (`ALL_CUSTOMERS`, `ALL_SUPPLIERS`, `ALL_CONTACTS`, `ALL_EMPLOYEES`, `ALL_USERS`) yields `datatypeCode: LIST`, a picklist of that population.
885
+ - **There is no NUMBER, DATE or DROPDOWN custom field, and `type`/`fieldType`/`entityType`/`datatypeCode`/`options` are all silently dropped** — sent with a value, they return 200 and the field is created as plain TEXT. Verified by readback across five spellings; `datatypeCode: 12345` also returns 200, so the DTO does not declare it. `datatypeCode` on the response is derived and read-only; `format` is settable on POST **and** PUT (both verified 2026-09-02).
889
886
 
890
887
  ### GET /api/v1/custom-fields/:resourceId
891
888
 
@@ -95,20 +95,18 @@ Or call `list_account_classifications` — authoritative for that organisation.
95
95
  **Fix**: Always include `printOnDocuments: false` (or `true`) in POST body. `create_custom_field` now sends `false` when you omit it, so this only bites a direct API caller.
96
96
  **Note**: recorded here as a 400 "Invalid request body" until 2026-09-02, when a live probe returned `422 validation_error` with the field named. Either the API tightened or the original entry generalised from a different malformed body; the 422 is what it returns today.
97
97
  ```json
98
- { "name": "PO Number", "type": "TEXT", "printOnDocuments": false }
98
+ { "name": "PO Number", "printOnDocuments": false, "appliesTo": { "invoices": true } }
99
99
  ```
100
100
 
101
- ### "Invalid request body" (400) appliesTo field
102
- **Cause**: Sending the `appliesTo` array field in the POST body.
103
- **Fix**: Do NOT send `appliesTo` it causes "Invalid request body". Only send: `name`, `type`, `printOnDocuments` (and `options` for DROPDOWN type).
101
+ ### WITHDRAWN "do not send appliesTo" on custom fields
102
+ This entry said `appliesTo` caused "Invalid request body" and told callers to send `type` and `options` instead. Re-probed live 2026-09-02: the opposite is true.
103
+ - `appliesTo` as an OBJECT works `{ "invoices": true, "bills": true }` returns 200 and sets `applyToSales`/`applyToPurchase` to `SHOW`. **Omitting it leaves every `applyTo*` at `NULL`, so the field appears on nothing.** The old entry's example sent an ARRAY (`["INVOICE"]`), which is the likely source of the original 400.
104
+ - `type`, `fieldType`, `entityType`, `datatypeCode` and `options` are all silently dropped: sent with a value they return 200 and the field is created as plain TEXT. There is no NUMBER/DATE/DROPDOWN custom field.
105
+ - `format` is the real control: `CUSTOM` (default) = free text, `ALL_*` = a picklist of that population.
104
106
  ```json
105
- // WRONG:
106
- { "name": "PO Number", "type": "TEXT", "printOnDocuments": false, "appliesTo": ["INVOICE"] }
107
-
108
- // CORRECT:
109
- { "name": "PO Number", "type": "TEXT", "printOnDocuments": false }
107
+ // Correct:
108
+ { "name": "PO Number", "printOnDocuments": false, "appliesTo": { "invoices": true, "bills": true } }
110
109
  ```
111
- Valid `type` values: `"TEXT"`, `"DATE"`, `"DROPDOWN"` (UPPERCASE).
112
110
 
113
111
  ---
114
112
 
@@ -383,8 +383,8 @@ DELETE → expects "A" (parentEntityResourceId, via /cash-entries/:id)
383
383
  | `name` (in GET response) | `customFieldName` | GET returns both `customFieldName` and `name` alias. |
384
384
  | `name` (in POST body) | `name` | POST accepts `name`. |
385
385
  | `showOnPdf` | `printOnDocuments` | Required boolean |
386
- | `appliesTo` | DO NOT SEND | Causes "Invalid request body" |
387
- | `type` values | `"TEXT"`, `"DATE"`, `"DROPDOWN"` | UPPERCASE strings |
386
+ | `appliesTo` | `appliesTo` (OBJECT) | `{invoices,bills,customerCredits,supplierCredits,payments,contacts,employeeClaims,fixedAssets,items,purchaseOrders,saleOrders}`. SEND IT omit it and the field appears on nothing. An ARRAY 400s, which is what the old "do not send" note measured |
387
+ | `type` / `fieldType` / `entityType` | — (silently dropped) | Use `format`: CUSTOM = free text, ALL_* = a picklist. `datatypeCode` is derived (TEXT or LIST); there is no NUMBER/DATE/DROPDOWN field |
388
388
 
389
389
  ### Custom Field Values on Transactions
390
390
 
@@ -246,7 +246,7 @@ Body for all three: `{ items: [{btResourceId: "<uuid>", btType: "SALE|PURCHASE|S
246
246
  | GET | `/contact-groups/:resourceId` | Get by ID |
247
247
  | POST | `/contact-groups` | Create |
248
248
  | POST | `/contact-groups/search` | Advanced search |
249
- | PUT | `/contact-groups/:resourceId` | Update (**known 500 bug**) |
249
+ | PUT | `/contact-groups/:resourceId` | Update membership field is `associatedContactResourceIds`, not `contactResourceIds` |
250
250
  | DELETE | `/contact-groups/:resourceId` | Delete |
251
251
 
252
252
  ### Items
@@ -293,7 +293,7 @@ Body for all three: `{ items: [{btResourceId: "<uuid>", btType: "SALE|PURCHASE|S
293
293
  | GET | `/custom-fields/:resourceId` | Get by ID |
294
294
  | POST | `/custom-fields` | Create |
295
295
  | POST | `/custom-fields/search` | Advanced search |
296
- | PUT | `/custom-fields/:resourceId` | Update (**known 500 bug** requires `appliesTo` but crashes) |
296
+ | PUT | `/custom-fields/:resourceId` | Update full replace of `appliesTo`+`printOnDocuments`; omitting either resets it |
297
297
  | DELETE | `/custom-fields/:resourceId` | Delete |
298
298
 
299
299
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-cli
3
- version: 5.47.1
3
+ version: 5.47.3
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.47.1
3
+ version: 5.47.3
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.47.1
3
+ version: 5.47.3
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.47.1
3
+ version: 5.47.3
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.47.1
3
+ version: 5.47.3
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.47.1
3
+ version: 5.47.3
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