jaz-clio 5.41.1 → 5.43.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.41.1
3
+ version: 5.43.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
@@ -172,7 +172,8 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
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
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.
175
- 47. **Non-existent endpoints**: `POST /deposits`, `POST /inventory/adjustments`, `GET /payments` (list), and `POST /payments/search` return 404 — these endpoints are not implemented. To list/search payments, use `POST /cashflow-transactions/search` (the unified transaction ledger — see Rule 63).
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
+ 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.
176
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`).
177
178
  49. **Currency rate direction: `rate` = functionalToSource (1 base = X foreign)** — POST `rate: 0.74` for a SGD org means 1 SGD = 0.74 USD. **If your data stores rates as "1 USD = 1.35 SGD" (sourceToFunctional), you MUST invert: `rate = 1 / 1.35 = 0.74`.** GET confirms both: `rateFunctionalToSource` (what you POSTed) and `rateSourceToFunctional` (the inverse). **You do not have to do the arithmetic**: `add_currency_rate`, `update_currency_rate` and the `currency` object on the 8 FX create tools (invoice, bill, journal, both credit notes, both cash entries, TTB) accept an optional `rateDirection` (`FUNCTIONAL_TO_SOURCE` | `SOURCE_TO_FUNCTIONAL`) — declare how your figure reads and pass it verbatim. Omitting it always means `FUNCTIONAL_TO_SOURCE`. The two families differ only in where the label is applied: the rate-table tools (plus `bulk_upsert_currency_rates`) send it on the wire and the server applies it, while the 8 FX create tools have no such field, so the client inverts and strips it there. Prefer either to inverting by hand: a wrong inversion is silent and wrong by rate². `clio calc fx-reval` REQUIRES the direction — that calculator historically assumed the opposite convention to the API.
178
179
 
@@ -184,7 +185,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
184
185
  51. **Filter operator reference** — An operator the target type does not declare is now rejected with a 400 naming it, not ignored, so use the exact set. String: `eq`, `neq`, `contains`, `notContains`, `in` (array, max 100), `likeIn` (array, max 100), `reg` (substring array, max 100 — a term match despite the name, not a regex), `startWith`, `notStartWith`, `endWith`, `notEndWith`, `isNull`, `isBlank`, `isNotBlank` (each takes the **string** `"true"`/`"false"`, not a bool). Numeric: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `inRange`/`notInRange` (exactly 2 values, low then high). Date (YYYY-MM-DD): `eq`, `gt`, `gte`, `lt`, `lte`, `between`/`notBetween` (exactly 2 values), `isNull`, `isNotNull`. DateTime (RFC3339): `eq`, `gt`, `gte`, `lt`, `lte`, `between`, converted to epoch ms internally. Boolean: `eq`. JSON: `jsonIn`, `jsonNotIn`. Logical: `and`/`or` objects everywhere; `andGroup`/`orGroup` arrays on invoices, bills, journals, cashflow transactions, payments, batch payments and the order family (orders, quotes, requests, line items) — **not** on credit notes. `not` exists only on contacts, items, tags, custom fields, tax profiles and nano classifiers; it is **not** available on invoices, bills or journals.
185
186
  52. **Date format asymmetry (CRITICAL)** — Request dates: `YYYY-MM-DD` strings (all create/update and DateExpression filters). Request datetimes: RFC3339 strings (DateTimeExpression filters for `createdAt`, `updatedAt`, `approvedAt`, `submittedAt`). **ALL response dates**: `int64` epoch milliseconds — including `valueDate`, `createdAt`, `updatedAt`, `approvedAt`, `submittedAt`, `matchDate`. Convert: `new Date(epochMs).toISOString().slice(0,10)`. **Timezone convention**: ALL business dates (`valueDate`, `dueDate`, `startDate`, `endDate`, etc.) are in the **organization's timezone** — never UTC. The epoch ms stored in the DB represents the org-local date (no timezone conversion is ever needed). Only audit timestamps (`createdAt`, `updatedAt`, `action_at`) are UTC.
186
187
  53. **Field aliases on create endpoints** — Middleware transparently maps: `issueDate`/`date` → `valueDate` (invoices, bills, credit notes, journals). `name` → `tagName` (tags) or `internalName` (items). `paymentDate` → `valueDate`, `bankAccountResourceId` → `accountResourceId` (payments). `paymentAmount` → `refundAmount`, `paymentMethod` → `refundMethod` (credit note refunds). `accountType` → `classificationType`, `currencyCode` → `currency` (CoA). Canonical names always work; aliases are convenience only.
187
- 54. **All search/list responses are flat** — every search and list endpoint returns `{ totalElements, totalPages, data: [...] }` directly (no outer `data` wrapper). Access the array via `response.data`, pagination via `response.totalElements`. **Two exceptions**: (a) `GET /bank-accounts` returns a plain array `[{...}]` (see Rule 18), (b) `GET /invoices/:id` returns a flat object `{...}` (no `data` wrapper) — unlike `GET /bills/:id`, `GET /contacts/:id`, `GET /journals/:id` which wrap in `{ data: {...} }`. Normalize the invoice GET response before use.
188
+ 54. **All search/list responses are flat** — every search and list endpoint returns `{ totalElements, totalPages, data: [...] }` directly (no outer `data` wrapper). Access the array via `response.data`, pagination via `response.totalElements`. **Three exceptions**: (a) `GET /bank-accounts` returns a plain array `[{...}]` (see Rule 18), (b) `GET /invoices/:id` returns a flat object `{...}` (no `data` wrapper) — unlike `GET /bills/:id`, `GET /contacts/:id`, `GET /journals/:id` which wrap in `{ data: {...} }`. Normalize the invoice GET response before use. (c) **The empty-result envelope on the scheduled-\* handlers changes shape**: when the upstream search block comes back null, eight handlers short-circuit to `{ "data": [], "pagination": { "total": 0 } }` — no `totalElements`, no `totalPages`, and a third pagination key name. The SAME endpoint returns the normal flat envelope the moment one row exists. Affected: list AND attachment-list on scheduled invoices, scheduled bills, scheduled journals, scheduled subscriptions. **Never read `totalElements` on a scheduled-\* response without falling back to `pagination.total`** — `response.totalElements ?? response.pagination?.total ?? 0` — and count rows off `data.length`, which is correct in both shapes.
188
189
  55. **Scheduled endpoints support date aliases** — `txnDateAliases` middleware (mapping `issueDate`/`date` → `valueDate`) now applies to all scheduled create/update endpoints: `POST/PUT /scheduled/invoices`, `POST/PUT /scheduled/bills`, `POST/PUT /scheduled/journals`, `POST/PUT /scheduled/subscriptions`.
189
190
  56. **Kebab-case URL aliases** — `capsuleTypes` endpoints also accept kebab-case paths: `/capsule-types` (list, search, CRUD). `moveTransactionCapsules` also accepts `/move-transaction-capsules`. Both camelCase and kebab-case work identically.
190
191
 
@@ -199,7 +200,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
199
200
  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" }`.
200
201
 
201
202
  ### Cashflow & Unified Ledger
202
- 64. **No standalone payments list/search** — `GET /payments`, `POST /payments/search`, and `GET /payments` do NOT exist. Per-payment CRUD (`GET/PUT/DELETE /payments/:resourceId`) exists for individual payment records, but to **list or search** payments, use `POST /cashflow-transactions/search` the unified transaction ledger that spans invoices, bills, credit notes, journals, cash entries, and payments. Filter by `businessTransactionType` (e.g., `SALE`, `PURCHASE`) and `direction` (`PAYIN`, `PAYOUT`). Response dates are epoch milliseconds.
203
+ 64. **Three 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.
203
204
  65. **Contacts search uses `name`** — NOT `billingName`. The filter field for searching contacts by name is `name` (maps to `billingName` internally). Sort field is also `name`. Using `billingName` in a search filter returns zero results.
204
205
 
205
206
  ### Response Shape Gotchas
@@ -221,7 +222,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
221
222
  ### Entity Resolution (Fuzzy Matching)
222
223
  78. **`--contact`, `--account`, and `--bank-account` accept names** — any CLI flag that takes a contact, chart of accounts entry, or bank account accepts EITHER a UUID resourceId OR a fuzzy name. Examples: `--contact "ACME Corp"`, `--account "DBS Operating"`, `--bank-account "Business"`. The CLI auto-resolves to the best match (strict thresholds) and shows the resolved entity on stderr. UUIDs are passed through without API calls. If the match is ambiguous, the CLI errors with a list of candidates — never silently picks the wrong entity.
223
224
  79. **`capsule-transaction` recipes auto-resolve accounts** — when `--input` is omitted, the CLI searches the org's chart of accounts for each blueprint account name (e.g., "Interest Expense", "Loan Payable"). If all accounts resolve with high confidence, no JSON mapping file is needed. If any fail, the error message shows exactly which accounts could not be found and suggests close matches. `--contact` and `--bank-account` on recipes also accept names.
224
- 80. **Payment/refund account filter is conditional on `--method`** for BANK_TRANSFER, CASH, and CHEQUE, the `--account` resolver filters to bank/cash accounts only. For other payment methods, all account types are considered.
225
+ 80. **Payment/refund account is gated by `paymentMethod`, not by the field's type** — the field itself accepts any chart-of-accounts id (the REST layer applies no type filter), but the platform then rejects anything outside Bank Accounts / Cash **when the method is BANK_TRANSFER, CASH or CHEQUE** — `INVALID_ACCOUNT_FOR_BUSINESS_TRANSACTION_FOUND`. Every other method reaches a non-bank account, which is the only way a deposit drawdown works: pay an invoice with `paymentMethod: OTHER` and `accountResourceId` set to the deposit account. The CLI mirrors this, filtering `--account` to bank/cash for those three methods only. Do not read the permissive field as permission — the REST layer is a proxy, and the accounting engine behind it is the authority.
225
226
 
226
227
  ### Draft Finalization Pipeline (Convert & Next)
227
228
 
@@ -318,9 +319,9 @@ Bills, invoices, and credit notes share identical mandatory field specs. Adding
318
319
  ### Fixed Assets
319
320
  91. **Fixed asset search does NOT support `createdAt` sort** — Valid sort fields: `resourceId`, `name`, `purchaseDate`, `typeName`, `purchaseAmount`, `bookValueNetBookValueAmount`, `depreciationMethod`, `status`. Using `createdAt` returns 422. Default to `purchaseDate` DESC.
320
321
  92. **Fixed asset disposal/sale/transfer use different endpoint patterns** — Discard: `POST /discard-fixed-assets/:id` (body includes `resourceId` + dates). Mark sold: `POST /mark-as-sold/fixed-assets` (body-only, no path param). Transfer: `POST /transfer-fixed-assets` (body-only). Undo: `POST /undo-disposal/fixed-assets/:id`.
321
- 92a. **Two ways to register fixed assets** — (1) **Create** (`POST /fixed-assets`): for assets purchased via a bill or journal already in the system. ACTIVE assets require `purchaseBusinessTransactionType` (`PURCHASE` or `JOURNAL_MANUAL`) and `purchaseBusinessTransactionResourceId`. (2) **Transfer** (`POST /transfer-fixed-assets`): for pre-existing assets purchased before using Jaz or outside the system. Accepts `bookValueAccumulatedDepreciationAmount` for depreciation already incurred. No linked transaction needed.
322
+ 92a. **Two ways to register fixed assets** — (1) **Create** (`POST /fixed-assets`): for assets purchased via a bill or journal already in the system. ACTIVE assets require `purchaseBusinessTransactionType` (`PURCHASE` or `JOURNAL_MANUAL`) and `purchaseBusinessTransactionResourceId` — **the resourceId of the purchase LINE ITEM (or the manual-journal entry), NOT the bill or journal document**. Passing the document id fails. The line item must also be UNLINKED: reusing one already attached to another asset fails with `ITEM_ALREADY_LINKED_WITH_ANOTHER_FIXED_ASSET`. (2) **Transfer** (`POST /transfer-fixed-assets`): for pre-existing assets purchased before using Jaz or outside the system. Accepts `bookValueAccumulatedDepreciationAmount` for depreciation already incurred. No linked transaction needed.
322
323
  92b. **`saveAsDraft` defaults to `true`** — To create an ACTIVE fixed asset, pass `saveAsDraft: false` with ALL required fields: `name`, `category`, `typeCode`, `purchaseAmount`, `purchaseDate`, `purchaseAssetAccountResourceId`, `depreciationMethod`, `effectiveLife`, and for `STRAIGHT_LINE`: `depreciationStartDate`, `accumulatedDepreciationAccountResourceId`, `depreciationExpenseAccountResourceId`. Omitting any returns 422.
323
- 92c. **Valid enums** — `depreciationMethod`: `STRAIGHT_LINE`, `NO_DEPRECIATION`. `category`: `TANGIBLE`, `INTANGIBLE`. Optional string fields (`purchaseBusinessTransactionResourceId`, `accumulatedDepreciationAccountResourceId`, `capsuleResourceId`) can be safely omitted — the API ignores empty values.
324
+ 92c. **Valid enums** — `depreciationMethod`: `STRAIGHT_LINE`, `NO_DEPRECIATION`. `category`: `TANGIBLE`, `INTANGIBLE`. `accumulatedDepreciationAccountResourceId` and `capsuleResourceId` can be safely omitted — the API ignores empty values. **`purchaseBusinessTransactionResourceId` is omittable ON DRAFTS ONLY** — and because `saveAsDraft` defaults to `true` here (Rule 92b — fixed assets are the one transaction type that drafts by default), omitting it looks like it worked right up until you set `saveAsDraft: false` and the create is rejected. On an ACTIVE asset it is required, and it is the purchase LINE ITEM's id — Rule 92a.
324
325
 
325
326
  ### Subscriptions & Scheduled Transactions
326
327
  93. **Subscription endpoints are under `/scheduled/subscriptions`** — List, GET, POST, PUT, DELETE all at `/api/v1/scheduled/subscriptions[/:id]`. Cancel is **PUT** (not POST) at `/api/v1/scheduled/cancel-subscriptions/:id` (different path pattern). **Subscriptions are invoices only** (SALE) — no bills. Different from scheduled invoices: subscriptions auto-prorate partial periods (generate credit notes for mid-period changes), but currency/tax/account are immutable after creation. Use scheduled invoices for fixed-amount recurring invoices where you need per-occurrence flexibility. **All subscription CRUD requires `proratedConfig: { proratedAdjustmentLineText: string }`** — Clio auto-injects this; do not add manually. **`repeat` is required on POST** (valid: `ONE_TIME`, `DAILY`, `WEEKLY`, `MONTHLY`, `YEARLY`) — Clio maps from the `interval` parameter. Cancel requires `cancelDateType` (`END_OF_CURRENT_PERIOD`, `END_OF_LAST_PERIOD`, `CUSTOM_DATE`) + `proratedAdjustmentLineText` + `resourceId` in body. Must cancel before delete. `businessTransactionType` is NOT in the OAS — the API ignores it.
@@ -74,13 +74,14 @@ Resources MUST be created in this order. Steps at the same level can run in para
74
74
  - `POST /scheduled/bills` → create bill schedulers (needs contacts + CoA)
75
75
 
76
76
  ### Level 5b: Optional/Experimental (Parallel)
77
- - POST /api/v1/catalogs (needs Items from Level 2)
78
- - POST /api/v1/deposits (needs Contacts + CoA-Bank from Level 0-1)
79
- - POST /api/v1/fixed-assets (needs CoA from Level 0-1)
80
- - POST /api/v1/inventory/adjustments (needs Items from Level 2)
77
+ - `POST /api/v1/catalogs` (needs Items from Level 2)
78
+ - `POST /api/v1/fixed-assets` (needs CoA from Level 0-1)
79
+ - **Deposit movements** — `POST /api/v1/journals` or `POST /api/v1/invoices/:id/payments` / `POST /api/v1/bills/:id/payments` against a deposit-flagged CoA account with `paymentMethod: OTHER` (BANK_TRANSFER/CASH/CHEQUE force a bank account — Rule 80) (needs Contacts + a CoA account someone has already flagged `depositContactType` in the web app; the flag cannot be set over the API). There is no `POST /api/v1/deposits` — SKILL.md Rule 47a.
81
80
 
82
81
  These endpoints may not be available on all organizations. Use try/catch with graceful fallback.
83
82
 
83
+ **No inventory adjustment step exists at any level** — `POST /api/v1/inventory/adjustments` and its three sibling spellings all 404. Stock moves only as a side effect of a transaction carrying the item. See `errors.md` → Inventory Adjustments Errors.
84
+
84
85
  ### Level 6: Verification
85
86
  - `POST /generate-reports/trial-balance` → verify data integrity
86
87
 
@@ -1740,31 +1740,42 @@ POST /api/v1/catalogs
1740
1740
 
1741
1741
  ---
1742
1742
 
1743
- ## Deposits (Experimental)
1744
-
1745
- > Endpoint availability varies by organization. Use try/catch.
1746
-
1747
- ### Create Deposit
1748
- POST /api/v1/deposits
1749
- ```json
1750
- {
1751
- "contactResourceId": "contact-uuid",
1752
- "depositDate": "2026-02-01",
1753
- "amount": 5000.00,
1754
- "type": "AR",
1755
- "bankAccountResourceId": "bank-account-uuid",
1756
- "currencyCode": "SGD"
1757
- }
1758
- ```
1759
-
1760
- - `type`: `"AR"` (accounts receivable / customer deposit) or `"AP"` (accounts payable / supplier deposit)
1761
- - `depositDate`: YYYY-MM-DD format
1762
- - `bankAccountResourceId`: Must be a CoA entry with accountType "Bank Accounts"
1763
-
1764
- ### Response
1765
- ```json
1766
- { "data": { "resourceId": "deposit-uuid" } }
1767
- ```
1743
+ ## Deposits (no endpoint — by design)
1744
+
1745
+ > **There is no deposits entity.** No `/deposits` route exists at any spelling and none is
1746
+ > planned. A deposit is a *flag on a Chart of Accounts account*, not a document. See
1747
+ > `feature-glossary.md` → Deposits for the business model, `errors.md` → Deposits Errors for
1748
+ > the 404.
1749
+
1750
+ **The flag**: a CoA account carries `depositContactType` — `CUSTOMER` (customer deposit /
1751
+ advance received, a liability), `SUPPLIER` (supplier deposit / advance paid, an asset), or
1752
+ `NULL` (an ordinary account).
1753
+
1754
+ **The movement**: once an account is flagged, a deposit is an *ordinary transaction posted
1755
+ against that account*. Nothing about the call is deposit-specific. The transaction types that
1756
+ land on a deposit account are the normal ones — `SALE`, `PURCHASE`, `PAYMENT_SALE`,
1757
+ `PAYMENT_PURCHASE`, `JOURNAL_DIRECT_CASH_IN`, `JOURNAL_DIRECT_CASH_OUT`, `JOURNAL_MANUAL`.
1758
+
1759
+ | Movement | Call |
1760
+ |----------|------|
1761
+ | Top up (advance received or paid) | `POST /api/v1/journals`, or `POST /api/v1/cash-in-entries` / `POST /api/v1/cash-out-entries` — one leg on the flagged account |
1762
+ | Draw down against an invoice | `POST /api/v1/invoices/:resourceId/payments` with `accountResourceId` = the flagged account **and `paymentMethod: "OTHER"`** |
1763
+ | Draw down against a bill | `POST /api/v1/bills/:resourceId/payments` with `accountResourceId` = the flagged account **and `paymentMethod: "OTHER"`** |
1764
+ | Read deposit movements | `POST /api/v1/cashflow-transactions/search` filtered on the flagged account's `organizationAccountResourceId` |
1765
+
1766
+ > **The payment method is load-bearing on a drawdown.** The platform gates the payment
1767
+ > account's TYPE on the method: `BANK_TRANSFER`, `CASH` and `CHEQUE` require a Bank
1768
+ > Accounts or Cash account and reject anything else with
1769
+ > `INVALID_ACCOUNT_FOR_BUSINESS_TRANSACTION_FOUND`. A deposit account is a Liability or
1770
+ > Asset by construction, so it is only reachable under another method — `OTHER` is the
1771
+ > plain choice. The tools default `paymentMethod` to `BANK_TRANSFER`, so a drawdown that
1772
+ > does not set it explicitly will 422. See SKILL.md Rule 80.
1773
+
1774
+ **What the API cannot do**: `depositContactType` is not on any chart-of-accounts request or
1775
+ response model in this API, and the platform-backend mutation that sets it
1776
+ (`configureDepositAccounts`) is not proxied. **Flagging an account as a deposit account is a
1777
+ web-app action.** `POST /chart-of-accounts` cannot create one. Over the API you can only read
1778
+ and post against an account someone already flagged.
1768
1779
 
1769
1780
  ---
1770
1781
 
@@ -1835,30 +1846,24 @@ Register an asset purchased before using Jaz, with accumulated depreciation.
1835
1846
 
1836
1847
  ---
1837
1848
 
1838
- ## Inventory Adjustments (Experimental)
1849
+ ## Inventory (read-only balances — no adjustment write path)
1839
1850
 
1840
- > Endpoint availability varies by organization. Use try/catch.
1851
+ > **There is no stock-adjustment endpoint at any spelling.** `POST /inventory/adjustments`,
1852
+ > `/inventory-adjustments`, `/inventory-items/:id/adjustments` and
1853
+ > `/items/:id/inventory-adjustments` all 404 — none is registered. See `errors.md` →
1854
+ > Inventory Adjustments Errors.
1841
1855
 
1842
- ### Create Adjustment
1843
- POST /api/v1/inventory/adjustments
1844
- ```json
1845
- {
1846
- "itemResourceId": "inventory-item-uuid",
1847
- "quantity": 50,
1848
- "adjustmentDate": "2026-02-01",
1849
- "reason": "Initial stock count",
1850
- "accountResourceId": "inventory-coa-uuid"
1851
- }
1852
- ```
1856
+ The complete inventory surface is three routes plus the item create/list pair:
1853
1857
 
1854
- - `quantity`: Positive integer (adjustment amount)
1855
- - `adjustmentDate`: YYYY-MM-DD format
1856
- - `itemResourceId`: Must reference an inventory-type item (not service)
1858
+ | Method | Path | Notes |
1859
+ |--------|------|-------|
1860
+ | POST | `/api/v1/inventory-items` | Create an inventory-tracked item |
1861
+ | GET | `/api/v1/inventory-items` | List inventory-tracked items |
1862
+ | GET | `/api/v1/inventory-item-balance/:resourceId` | Balance for one item |
1863
+ | GET | `/api/v1/inventory-balances/:balanceStatus` | Balances by status — **returns 500**, see SKILL.md Rule 46 |
1857
1864
 
1858
- ### Response
1859
- ```json
1860
- { "data": { "resourceId": "adjustment-uuid" } }
1861
- ```
1865
+ Stock moves only as a side effect of a transaction that carries the item (invoice, bill,
1866
+ credit note). There is no direct quantity write.
1862
1867
 
1863
1868
  ---
1864
1869
 
@@ -2154,6 +2159,79 @@ Same for `GET /bills/{resourceId}/payments`, `GET /invoices/{resourceId}/credits
2154
2159
 
2155
2160
  ---
2156
2161
 
2162
+ ## 19c. Request Changes (REST only — no CLI or MCP wrapper)
2163
+
2164
+ Sends a **submitted** record back to its creator for edits: the record returns to draft, its
2165
+ approval markers are cleared, and `message` is posted as the first comment on a new
2166
+ collaboration thread. Records in any other state are skipped and reported in the response.
2167
+
2168
+ > **No wrapper exists.** These 18 routes have no `clio` subcommand, no MCP tool, and no
2169
+ > `src/core/api/` client function. Call them with a raw HTTP request — do not go looking for a
2170
+ > tool that does not exist.
2171
+
2172
+ Nine entities, each with a single-record and a bulk form:
2173
+
2174
+ | Entity | Single | Bulk |
2175
+ |--------|--------|------|
2176
+ | Invoices | `POST /api/v1/invoices/:resourceId/request-changes` | `POST /api/v1/invoices/bulk-request-changes` |
2177
+ | Bills | `POST /api/v1/bills/:resourceId/request-changes` | `POST /api/v1/bills/bulk-request-changes` |
2178
+ | Customer credit notes | `POST /api/v1/customer-credit-notes/:resourceId/request-changes` | `POST /api/v1/customer-credit-notes/bulk-request-changes` |
2179
+ | Supplier credit notes | `POST /api/v1/supplier-credit-notes/:resourceId/request-changes` | `POST /api/v1/supplier-credit-notes/bulk-request-changes` |
2180
+ | Purchase orders | `POST /api/v1/purchase-orders/:resourceId/request-changes` | `POST /api/v1/purchase-orders/bulk-request-changes` |
2181
+ | Purchase requests | `POST /api/v1/purchase-requests/:resourceId/request-changes` | `POST /api/v1/purchase-requests/bulk-request-changes` |
2182
+ | Sale orders | `POST /api/v1/sale-orders/:resourceId/request-changes` | `POST /api/v1/sale-orders/bulk-request-changes` |
2183
+ | Sale quotes | `POST /api/v1/sale-quotes/:resourceId/request-changes` | `POST /api/v1/sale-quotes/bulk-request-changes` |
2184
+ | Claims | `POST /api/v1/claims/:resourceId/request-changes` | `POST /api/v1/claims/bulk/request-changes` |
2185
+
2186
+ **Claims breaks the bulk path pattern** — `/claims/bulk/request-changes`, not
2187
+ `/claims/bulk-request-changes`. The other eight are all `bulk-request-changes`.
2188
+
2189
+ ### Single — request body (200)
2190
+ ```json
2191
+ { "message": "Please attach the signed delivery note before resubmitting." }
2192
+ ```
2193
+ `message` is required and `minLength: 1` — a blank value is rejected. It is the only place the
2194
+ reason is recorded.
2195
+
2196
+ ```json
2197
+ // Response — 200 (per-record outcome; a skipped record does NOT fail the call)
2198
+ {
2199
+ "data": {
2200
+ "records": [
2201
+ {
2202
+ "resourceId": "...",
2203
+ "isSuccess": true,
2204
+ "status": "DRAFT",
2205
+ "approvalStatus": "...",
2206
+ "collaborationThreadPath": "...",
2207
+ "errorCode": null,
2208
+ "failureReason": null
2209
+ }
2210
+ ]
2211
+ }
2212
+ }
2213
+ ```
2214
+ **Check `isSuccess` per record** — a record in the wrong state comes back with
2215
+ `isSuccess: false` + `errorCode`/`failureReason`, inside a 200.
2216
+
2217
+ ### Bulk — request body (202)
2218
+ ```json
2219
+ {
2220
+ "message": "Please attach the signed delivery note before resubmitting.",
2221
+ "resourceIds": ["b7a2c3d4-e5f6-7890-abcd-ef1234567890"]
2222
+ }
2223
+ ```
2224
+ `resourceIds`: 1–500 per call. `message` applies to every record in the batch.
2225
+
2226
+ ```json
2227
+ // Response — 202 (async job handle, NOT the outcome)
2228
+ { "data": { "jobId": "...", "status": "...", "totalRecords": 12, "totalChunks": 1, "subscriptionFBPath": "..." } }
2229
+ ```
2230
+ Poll the result with `POST /api/v1/background-jobs/search` (section 23) — the 202 only means
2231
+ the job was accepted.
2232
+
2233
+ ---
2234
+
2157
2235
  ## 20. Nano-Classifier CRUD
2158
2236
 
2159
2237
  ### POST /api/v1/nano-classifiers — Create
@@ -586,17 +586,34 @@ if (acct.code) ctx.coaIds[acct.code] = acct.resourceId;
586
586
 
587
587
  ## Deposits Errors
588
588
 
589
- ### 404 — Endpoint does not exist
590
- **Cause**: `POST /deposits` returns 404. Also tested: `/customer-deposits`, `/supplier-deposits`, `/cash-entries`, `/cash-in`, `/cash-out` — all 404.
591
- **Note**: This endpoint is not implemented in the API. No workaround.
589
+ ### 404 on `POST /deposits` CORRECT and expected
590
+ **Cause**: There is no deposits entity, by design. `POST /deposits` 404s, and so do
591
+ `/customer-deposits`, `/supplier-deposits`, `/cash-in` and `/cash-out`. Nothing is broken and
592
+ nothing is missing — a deposit is not a document.
593
+ **Fix**: Post against a **deposit-flagged Chart of Accounts account** instead. The account
594
+ carries `depositContactType` = `CUSTOMER` or `SUPPLIER`; a deposit is then an ordinary
595
+ transaction on it.
596
+ - Top up: `POST /journals`, `POST /cash-in-entries`, `POST /cash-out-entries` — one leg on the flagged account.
597
+ - Draw down against an invoice or bill: `POST /invoices/:resourceId/payments` or `POST /bills/:resourceId/payments` with `accountResourceId` = the flagged account.
598
+ - Read movements: `POST /cashflow-transactions/search` on that account.
599
+
600
+ **Setting the flag is a web-app action** — `depositContactType` is not on any
601
+ chart-of-accounts model in this API, so `POST /chart-of-accounts` cannot create a deposit
602
+ account. Full model: SKILL.md Rule 47a, `endpoints.md` → Deposits, `feature-glossary.md` → Deposits.
603
+
604
+ **`/cash-entries` is NOT a 404 path** — an earlier version of this note listed it. A bare
605
+ `POST /cash-entries` has no handler, but the prefix is live:
606
+ `DELETE /cash-entries/:resourceId`, `POST /cash-entries/bulk-upsert` and
607
+ `POST /cash-entries/bulk-delete` all exist. Single cash entries are created at
608
+ `POST /cash-in-entries` / `POST /cash-out-entries`.
592
609
 
593
610
  ---
594
611
 
595
612
  ## Inventory Adjustments Errors
596
613
 
597
614
  ### 404 — Endpoint does not exist
598
- **Cause**: `POST /inventory/adjustments` returns 404. Also tested: `/inventory-adjustments`, `/inventory-items/:id/adjustments`, `/items/:id/inventory-adjustments` — all 404.
599
- **Note**: This endpoint is not implemented in the API. Inventory items can be created via `POST /inventory-items` but stock adjustments cannot be made via API.
615
+ **Cause**: `POST /inventory/adjustments` returns 404. Also tested: `/inventory-adjustments`, `/inventory-items/:id/adjustments`, `/items/:id/inventory-adjustments` — all 404. None of the four is registered; there is no stock-adjustment write path at any spelling.
616
+ **Note**: The whole inventory surface is `POST|GET /inventory-items`, `GET /inventory-item-balance/:resourceId` and `GET /inventory-balances/:balanceStatus` (that last one 500s — Rule 46). Inventory items can be created, and stock moves as a side effect of a transaction carrying the item, but quantity cannot be written directly. See `endpoints.md` → Inventory.
600
617
 
601
618
  ---
602
619
 
@@ -868,10 +885,6 @@ Two of the seven never reach you through this path: a zero `adjustmentValue` and
868
885
 
869
886
  ---
870
887
 
871
- *Last updated: 2026-03-13 — Added: Nano-classifier errors (classes field, double-wrapped GET), payment record errors (cashflow vs payment IDs), sub-resource raw array errors. Previous: Cash entry path migration, Quick Fix errors.*
872
-
873
- ---
874
-
875
888
  ## Claims Errors
876
889
 
877
890
  ### "CLAIM_REFERENCE_REQUIRED_AT_SUBMIT" (422)
@@ -80,9 +80,11 @@ Track advance payments and prepaid balances. Customer deposits are liabilities (
80
80
 
81
81
  Can block payments if deposit balance is insufficient. View all contacts with deposits and filter by balance status. Managed via dedicated deposit accounts in the Chart of Accounts.
82
82
 
83
- There is no dedicated `/deposits` endpoint (returns 404). Deposits are managed through deposit-designated CoA accounts, with transactions recorded as journal entries and payments on invoices/bills drawing from those deposit accounts.
83
+ **The mechanism**: an account is marked as a deposit account by `depositContactType` on the chart-of-accounts record — `CUSTOMER` (advance received, a liability), `SUPPLIER` (advance paid, an asset), or `NULL` (an ordinary account). The flag is set by the platform-backend mutation `configureDepositAccounts`. **Neither is exposed on this API**, so flagging an account is a web-app action; over the API you can only read and post against an account someone already flagged. `POST /chart-of-accounts` cannot create one.
84
84
 
85
- **API**: `POST /journals` (record deposit top-ups/drawdowns via deposit CoA accounts), `POST /chart-of-accounts` (create deposit accounts), `POST /invoices/:id/payments` / `POST /bills/:id/payments` (draw from deposit account via `accountResourceId`)
85
+ There is no dedicated `/deposits` endpoint (returns 404) and none is planned — a deposit is not a document. Once an account is flagged, a deposit movement is an ordinary transaction against it, carrying the ordinary `businessTransactionType` values (`SALE`, `PURCHASE`, `PAYMENT_SALE`, `PAYMENT_PURCHASE`, `JOURNAL_DIRECT_CASH_IN`, `JOURNAL_DIRECT_CASH_OUT`, `JOURNAL_MANUAL`).
86
+
87
+ **API**: `POST /journals` / `POST /cash-in-entries` / `POST /cash-out-entries` (top up or draw down — one leg on the flagged account), `POST /invoices/:id/payments` / `POST /bills/:id/payments` (draw the deposit down against a document via `accountResourceId`, with `paymentMethod: OTHER` — BANK_TRANSFER/CASH/CHEQUE force a bank account and 422), `POST /cashflow-transactions/search` (read movements). Authoritative version: SKILL.md Rule 47a.
86
88
 
87
89
  ---
88
90
 
@@ -681,4 +681,4 @@ Battle-tested patterns from production Jaz API clients:
681
681
 
682
682
  ---
683
683
 
684
- *Last updated: 2026-04-09 — Added: Background Jobs (resourceId vs jobId critical trap, startedAt broken), Export Records (fileUrl, filterDescription, previewRows keying). Previous: 2026-03-13 — Payment record fields, scheduler field asymmetry, nano-classifier fields.*
684
+ *Hand-maintained and not regenerated; nothing detects it going stale — provenance and precedence rules: `search-enums.md` → Provenance and staleness. Last updated: 2026-04-09 — Added: Background Jobs (resourceId vs jobId critical trap, startedAt broken), Export Records (fileUrl, filterDescription, previewRows keying). Previous: 2026-03-13 — Payment record fields, scheduler field asymmetry, nano-classifier fields.*
@@ -1,8 +1,15 @@
1
- # Jaz API — Complete Endpoint Catalog
2
-
3
- > Every endpoint in the Jaz REST API, organized by resource. Includes undocumented
4
- > endpoints, magic AI features, admin APIs, and advanced search/filter syntax.
5
- > For request/response examples of core endpoints, see endpoints.md.
1
+ # Jaz API — Endpoint Catalog
2
+
3
+ > **The endpoints clio wraps — the REST surface is larger.** This file catalogues roughly 200
4
+ > paths, organized by resource, including undocumented endpoints, magic AI features, admin
5
+ > APIs, and advanced search/filter syntax. The committed OpenAPI spec (`spec/openapi.yaml`)
6
+ > carries 440 paths / 358 operations and is the authoritative list; check it before concluding
7
+ > an endpoint does not exist. For request/response examples of core endpoints, see
8
+ > endpoints.md.
9
+ >
10
+ > **Paths below are written without the `/api/v1` prefix.** Every one of them is really
11
+ > `/api/v1/<path>`. Recent additions not yet folded into the tables are listed at the end
12
+ > under "2026-08 additions".
6
13
 
7
14
  ---
8
15
 
@@ -766,4 +773,73 @@ See endpoints.md section 25 for request/response shapes and the `refs` grammar (
766
773
 
767
774
  ---
768
775
 
769
- *Last updated: 2026-07-11 (added Jots judgment journal: 3 endpoints). Previous: 2026-04-29 — Added 3 drafts lifecycle endpoints (validate, convert-to-active, submit-for-approval) — bulk-friendly, mixed-type batches up to 500. Same day: 8 reconciliation action endpoints; 8 bulk-upsert endpoints. 2026-04-09 — Background Jobs, Export Records, contacts bulk-upsert.*
776
+ ## Additions since 2026-07-11
777
+
778
+ Live routes added after the tables above were last regenerated. None has a `clio` subcommand
779
+ or an MCP tool — call them with a raw request.
780
+
781
+ ### Request changes (18) — 2026-08-06
782
+
783
+ `POST /{entity}/:resourceId/request-changes` and `POST /{entity}/bulk-request-changes` for
784
+ `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `purchase-orders`,
785
+ `purchase-requests`, `sale-orders`, `sale-quotes`. Claims uses a different bulk shape:
786
+ `POST /claims/:resourceId/request-changes` + `POST /claims/bulk/request-changes`.
787
+ Bodies and per-record outcome semantics: endpoints.md section 19c.
788
+
789
+ ### Payments, bulk and batch (9) — 2026-08-13
790
+
791
+ | Method | Path | Description |
792
+ |--------|------|-------------|
793
+ | POST | `/sales/payments/search` | Search sale payments (see SKILL.md Rule 64) |
794
+ | POST | `/purchases/payments/search` | Search purchase payments |
795
+ | POST | `/sales/bulk-payments` | Record many sale payments |
796
+ | POST | `/sales/batch-payments` | Record a sale payment batch |
797
+ | POST | `/purchases/bulk-payments` | Record many purchase payments |
798
+ | POST | `/purchases/batch-payments` | Record a purchase payment batch |
799
+ | POST | `/payments/bulk-delete` | Delete many payments |
800
+ | POST | `/batch-payments/search` | Search payment batches |
801
+ | POST | `/batch-payments/bulk-delete` | Delete many payment batches |
802
+
803
+ ### Cash entries and transfers, bulk (3) — 2026-08-13
804
+
805
+ | Method | Path | Description |
806
+ |--------|------|-------------|
807
+ | POST | `/cash-entries/bulk-upsert` | Bulk create/update cash entries |
808
+ | POST | `/cash-entries/bulk-delete` | Bulk delete cash entries |
809
+ | POST | `/cash-transfers/bulk-upsert` | Bulk create/update cash transfers |
810
+
811
+ Neither bulk cash route applies the `issueDate`/`date` → `valueDate` aliases their
812
+ single-create siblings do — the alias middleware rewrites the top-level body only, and on
813
+ these routes the aliased keys sit inside the `cashEntries[]` / `cashTransfers[]` rows. Send
814
+ `valueDate` on bulk rows.
815
+
816
+ ### Record-list option pickers (4) — 2026-08-12
817
+
818
+ | Method | Path | Description |
819
+ |--------|------|-------------|
820
+ | GET | `/record-lists/:format/options` | Options for a record-list format |
821
+ | POST | `/record-lists/:format/resolve` | Resolve a record list |
822
+ | GET | `/custom-fields/:resourceId/options` | Options for a custom field |
823
+ | GET | `/nano-classifiers/:resourceId/options` | Options for a nano-classifier |
824
+
825
+ ### Bank-record archive (2) — 2026-08-15
826
+
827
+ | Method | Path | Description |
828
+ |--------|------|-------------|
829
+ | POST | `/bank-records/:accountResourceId/archive` | Archive bank records |
830
+ | POST | `/bank-records/:accountResourceId/unarchive` | Unarchive bank records |
831
+
832
+ ### Withholding (1) — 2026-07-31
833
+
834
+ | Method | Path | Description |
835
+ |--------|------|-------------|
836
+ | POST | `/payments/withholding` | Record withholding on a sale / sale credit note payment (see SKILL.md Rule 45) |
837
+
838
+ ---
839
+
840
+ *Last updated: 2026-08-16 (added the "Additions since 2026-07-11" section: request-changes ×18, payments bulk/batch ×9, cash bulk ×3, record-list option pickers ×4, bank-record archive ×2, withholding ×1; dropped the "every endpoint" claim — the tables above cover the endpoints clio wraps, not the whole surface). Previous: 2026-07-11 (added Jots judgment journal: 3 endpoints). 2026-04-29 — Added 3 drafts lifecycle endpoints (validate, convert-to-active, submit-for-approval) — bulk-friendly, mixed-type batches up to 500. Same day: 8 reconciliation action endpoints; 8 bulk-upsert endpoints. 2026-04-09 — Background Jobs, Export Records, contacts bulk-upsert.*
841
+
842
+ **Regeneration note**: this file is hand-maintained and NOT covered by the drift gate (whose
843
+ `docsPaths` lists `endpoints.md` alone, and which only reads `### METHOD /api/v1/...` headers).
844
+ Nothing catches it going stale. Re-derive it from `spec/openapi.yaml` whenever the spec
845
+ refresh lands, and treat the spec as authoritative on any disagreement.
@@ -247,12 +247,14 @@ Used by: invoices, bills, credit notes, journals, items, scheduled transactions,
247
247
 
248
248
  | Field | Valid Values |
249
249
  |-------|-------------|
250
- | `status` | `ACTIVE`, `DRAFT`, `DISPOSED`, `SOLD`, `DISCARDED`, `COMPLETED`, `ONGOING` |
250
+ | `status` | `ACTIVE`, `ONGOING`, `COMPLETED`, `DRAFT`, `DISPOSED`, `SOLD`, `DISCARDED`, `CLOSED_OUT` |
251
251
  | `category` | `TANGIBLE`, `INTANGIBLE` |
252
252
  | `depreciationMethod` | `NO_DEPRECIATION`, `STRAIGHT_LINE` |
253
253
  | `disposalType` | `SOLD`, `DISCARDED` |
254
254
  | `registrationType` | `NEW`, `TRANSFER` |
255
255
 
256
+ **Two status enums**: the 8 values above are the VIEW status, which is what the search filter resolves against. A fixed asset RECORD's own `status` field only ever holds `DRAFT`, `ACTIVE`, `DISPOSED`, or `CLOSED_OUT` — so `ONGOING`, `COMPLETED`, `SOLD`, and `DISCARDED` narrow the search but never come back in a record's `status`.
257
+
256
258
  **Amount fields**: `purchaseAmount`, `bookValueAmount`, `netBookAtDisposalAmount`, `assetDisposalGainLossAmount`
257
259
  **Date fields**: `purchaseDate`, `disposalValueDate`, `depreciationStartDate`, `depreciationEndDate`
258
260
  **String fields**: `name`, `reference`, `typeName`, `typeCode`, `tags`, `currencyCode`, `purchaseBusinessTransactionType`
@@ -523,4 +525,31 @@ All search endpoints return:
523
525
 
524
526
  ---
525
527
 
526
- *Source of truth: Jaz API backend Go structs + OpenAPI specification. Last updated: 2026-03-31.*
528
+ ## Provenance and staleness (applies to the search reference files)
529
+
530
+ **This file is derived, not authoritative.** The enum values live in exactly one place in
531
+ code — `src/core/search/enums.ts` — which is what the entity configs, the MCP tool schemas
532
+ and the CLI flag choices all import. Upstream of that sits the committed `spec/openapi.yaml`.
533
+ Precedence on any disagreement:
534
+
535
+ ```
536
+ spec/openapi.yaml → src/core/search/enums.ts → this file (and search-reference.md,
537
+ field-map.md, full-api-surface.md)
538
+ ```
539
+
540
+ If a value here disagrees with `enums.ts`, **this file is wrong** — fix it here and do not
541
+ "fix" the code to match. If `enums.ts` disagrees with the spec, the spec wins and both need
542
+ updating.
543
+
544
+ **These four reference files are hand-maintained and nothing regenerates them.** The drift
545
+ gate reads `endpoints.md` alone, and only its `### METHOD /api/v1/...` headers, so a stale
546
+ enum table here fails silently and forever. Re-derive them on the same cadence as the spec
547
+ refresh. When adding a NEW enum, add it to `enums.ts` first and reference it here rather than
548
+ restating the values — the same enum is currently written out in up to five places, and every
549
+ one of them has to be touched for a single upstream change.
550
+
551
+ ---
552
+
553
+ *Derived from `src/core/search/enums.ts` + the committed OpenAPI specification. Enum tables
554
+ above last re-derived: 2026-03-31 — treat any value not confirmed against `enums.ts` as
555
+ unverified.*
@@ -839,4 +839,4 @@ POST /api/v1/cashflow-transactions/search
839
839
 
840
840
  ---
841
841
 
842
- *Source of truth: Go structs in the API backend (`models/*.go`). All filter/sort fields extracted from Go struct validation tags and verified against live production API. Last updated: 2026-02-14 — All search/list responses standardized to flat shape. Capsules/capsuleTypes sort now array. Purchase-items sort fields corrected. Tax-profiles max fixed. Catalogs search returns paginated response.*
842
+ *Derived from Go structs in the API backend (`models/*.go`) filter/sort fields extracted from struct validation tags and verified against the live production API. **Hand-maintained and not regenerated; nothing detects it going stale** — provenance and precedence rules: `search-enums.md` → Provenance and staleness. Last re-derived: 2026-02-14 — All search/list responses standardized to flat shape. Capsules/capsuleTypes sort now array. Purchase-items sort fields corrected. Tax-profiles max fixed. Catalogs search returns paginated response.*
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-cli
3
- version: 5.41.1
3
+ version: 5.43.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,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-conversion
3
- version: 5.41.1
3
+ version: 5.43.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.41.1
3
+ version: 5.43.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.41.1
3
+ version: 5.43.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.41.1
3
+ version: 5.43.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,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-recipes
3
- version: 5.41.1
3
+ version: 5.43.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