jaz-clio 5.46.8 → 5.46.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/skills/api/SKILL.md +8 -4
- package/assets/skills/cli/SKILL.md +1 -1
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jaz-kit/SKILL.md +1 -1
- package/assets/skills/jaz-pseudo-sql/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +1 -1
- package/assets/skills/transaction-recipes/SKILL.md +1 -1
- package/cli.mjs +290 -290
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jaz-api
|
|
3
|
-
version: 5.46.
|
|
3
|
+
version: 5.46.10
|
|
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
|
|
@@ -388,9 +388,9 @@ Bills, invoices, and credit notes share identical mandatory field specs. Adding
|
|
|
388
388
|
|
|
389
389
|
### Bulk Upserts (transactions)
|
|
390
390
|
|
|
391
|
-
118. **8 bulk-upsert endpoints for transactions** — `POST /api/v1/{invoices,bills,customer-credit-notes,supplier-credit-notes,journals,fixed-assets}/bulk-upsert` plus line-item variants for invoices and bills (`/invoices/line-items/bulk-upsert`, `/bills/line-items/bulk-upsert`). Max **500 rows per call**. All async — return `{data: {jobId, subscriptionFBPath, status, totalRecords}}`. Poll `search_background_jobs` with `filter: {resourceId: {eq: jobId}}` until terminal status. **Natural keys**: invoices = `invoiceReference`, bills = `billReference`, credit notes = `creditNoteReference`, **journals = `journalReference` (NOT `reference` — asymmetric vs other entities)**, fixed assets = `reference`. **`currencyCode` is REQUIRED** on every transaction row (invoices, bills, CCN, SCN) — missing it returns errorCode `IMPORT_CURRENCY_REQUIRED`. **Journals are the exception**: the bulk journal row has no currency field and any `currencyCode` sent is discarded, and the public request model exposes no per-leg currency field either. **Journals legs use `journalEntries[]`** (NOT `entries[]` — different from `journals create` which uses entries), and **a journal leg is `organizationAccountResourceId` + exactly one of `debitAmount`/`creditAmount`** — NOT the `accountResourceId`+`amount`+`type` shape `journals create` takes, and omit the unused side rather than sending 0.
|
|
391
|
+
118. **8 bulk-upsert endpoints for transactions** — `POST /api/v1/{invoices,bills,customer-credit-notes,supplier-credit-notes,journals,fixed-assets}/bulk-upsert` plus line-item variants for invoices and bills (`/invoices/line-items/bulk-upsert`, `/bills/line-items/bulk-upsert`). Max **500 rows per call**. All async — return `{data: {jobId, subscriptionFBPath, status, totalRecords}}`. Poll `search_background_jobs` with `filter: {resourceId: {eq: jobId}}` until terminal status. **Natural keys**: invoices = `invoiceReference`, bills = `billReference`, credit notes = `creditNoteReference`, **journals = `journalReference` (NOT `reference` — asymmetric vs other entities)**, fixed assets = `reference`. **`currencyCode` is REQUIRED** on every transaction row (invoices, bills, CCN, SCN) — missing it returns errorCode `IMPORT_CURRENCY_REQUIRED`. **Journals are the exception**: the bulk journal row has no currency field and any `currencyCode` sent is discarded, and the public request model exposes no per-leg currency field either. **Journals legs use `journalEntries[]`** (NOT `entries[]` — different from `journals create` which uses entries), and **a journal leg is `organizationAccountResourceId` + exactly one of `debitAmount`/`creditAmount`** — NOT the `accountResourceId`+`amount`+`type` shape `journals create` takes, and omit the unused side rather than sending 0. **On the six TRANSACTION bulk tools the natural key is the only upsert key — `resourceId` does not override it.** Probed live 2026-09-02 on invoices, bills, customer credit notes and invoice line items: sending an existing record's `resourceId` together with a DIFFERENT natural key left the original untouched and created a second record. (Supplier credit notes and bill line items were not probed; they were changed on their twin's evidence plus spec absence.) `resourceId` has been removed from all six. It remains valid, and spec-backed, on `bulk_upsert_contacts`, `bulk_upsert_items` and `bulk_upsert_chart_of_accounts` — see rule 137. Journals upsert by `journalReference` only. **Currency and due date split by shape, so pick the tool by what you need:** the FLAT pair (`bulk_upsert_invoices` / `bulk_upsert_bills`) IGNORES both — a row sent `currencyCode: EUR` against a USD-base org stored USD, omitting `currencyCode` entirely still succeeds, and `dueDate` comes back equal to `valueDate` with `terms: 0`. The NESTED pair (`bulk_upsert_invoice_line_items` / `bulk_upsert_bill_line_items`) honours `dueDate` (it is in fact REQUIRED there — omitting it fails the row with `DUE_DATE_REQUIRED`) and requires `currencyCode`. **So a bulk import that needs a real due date or a non-base currency must use the NESTED tools.** `tags` is on no transaction bulk wire definition and has been removed from these tools. `rowIndex` is optional caller-supplied for error reporting — on journals it sits on the leg, not the row.
|
|
392
392
|
|
|
393
|
-
118b. **Credit-note rows carry two extra requirements** (customer and supplier alike, and nothing here applies to journals). The tools speak `currencyCode`, but these two contracts — like the two line-item ones — name the wire field `transactionCurrency`; the client renames it for you via `toWireCurrencyRow`. They also require **`transactionRateType`** (`ORGANIZATION_RATE` | `TRANSACTION_RATE`): omit it and the row fails `IMPORT_TRANSACTION_RATE_TYPE_INVALID` even when the currency is right. `TRANSACTION_RATE` reads `rateFunctionToSource` (1 base unit = N transaction currency); `ORGANIZATION_RATE` uses the org rate. Neither endpoint carries `tags` on its wire definition, so do not report tags "applied" through this route. (The two line-item endpoints were probed the same way on 2026-09-02 and do NOT need `transactionRateType
|
|
393
|
+
118b. **Credit-note rows carry two extra requirements** (customer and supplier alike, and nothing here applies to journals). The tools speak `currencyCode`, but these two contracts — like the two line-item ones — name the wire field `transactionCurrency`; the client renames it for you via `toWireCurrencyRow`. They also require **`transactionRateType`** (`ORGANIZATION_RATE` | `TRANSACTION_RATE`): omit it and the row fails `IMPORT_TRANSACTION_RATE_TYPE_INVALID` even when the currency is right. `TRANSACTION_RATE` reads `rateFunctionToSource` (1 base unit = N transaction currency); `ORGANIZATION_RATE` uses the org rate. Neither endpoint carries `tags` on its wire definition, so do not report tags "applied" through this route. (The two line-item endpoints were probed the same way on 2026-09-02 and do NOT need `transactionRateType`.)
|
|
394
394
|
|
|
395
395
|
119. **PARTIAL_SUCCESS handling** — When `search_background_jobs` returns `PARTIAL_SUCCESS` for a bulk-upsert job, the per-row failures are in `data[0].errorDetails` on the SAME response (an array of per-row error objects). Top-level counts (`processedCount`, `failedCount`, `totalRecords`) tell you *how many* failed; `errorDetails` tells you *which rows and why*. Don't pretend the operation succeeded — surface the failed rows to the user. The rule of thumb: poll with `search_background_jobs` filtered by `resourceId: { eq: jobId }`, then read `data[0].errorDetails` for terminal states.
|
|
396
396
|
|
|
@@ -438,7 +438,11 @@ Bills, invoices, and credit notes share identical mandatory field specs. Adding
|
|
|
438
438
|
|
|
439
439
|
136. **Sync bulk-upsert response carries per-row failures** — `bulk_upsert_currency_rates` and `bulk_upsert_chart_of_accounts` return `{ resourceIds: string[], failedRows: ImportedRowError[], failedCount: number }` synchronously (no jobId polling needed). Each `failedRows` entry: `{ rowIndex, columnName, columnValue, errorCode, errorMessage }`. Empty `failedRows: []` + `failedCount: 0` on full success. For `bulk_upsert_currency_rates` specifically: omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (prevents temporal gaps in rate lookups). Contrast with async bulk-upserts (contacts, invoices, journals, etc.) which return `{ jobId }` and need `search_background_jobs` polling — there, per-row failures live in the job's `errorDetails` field instead.
|
|
440
440
|
|
|
441
|
-
137. **`bulk_upsert_contacts` request-level validation** — fails the WHOLE batch with HTTP 422 (no per-row partial success at this layer). Five rules to satisfy before submitting: (a) every contact must have `customer: true` OR `supplier: true` after defaults+backfill — for updates, the API backfills omitted flags from the existing contact; for creates, you must explicitly set at least one. (b)
|
|
441
|
+
137. **`bulk_upsert_contacts` request-level validation** — fails the WHOLE batch with HTTP 422 (no per-row partial success at this layer). Five rules to satisfy before submitting: (a) every contact must have `customer: true` OR `supplier: true` after defaults+backfill — for updates, the API backfills omitted flags from the existing contact; for creates, you must explicitly set at least one. (b) email entries within a contact must be case-insensitively unique (the tool takes `emails: string[]` and expands them to `emailList[{email,label}]`). (c) **Do NOT send payment terms here at all** — see rule 137c. The documented `{name, value}` shape returns SUCCESS and silently destroys the row. The tool does not expose the field. (d) `name` must be unique within the batch (after whitespace+case normalize). (e) When `billingAddress` or `shippingAddress` is provided, BOTH `addressLine1` and `country` are required (the tool calls the first one `address` and renames it for you). Pre-validate client-side before calling; one bad row rejects the entire batch and the agent loses any successful work-in-progress.
|
|
442
|
+
|
|
443
|
+
137a. **`bulk_upsert_contacts` — the tool speaks its own vocabulary and the client renames six keys at the wire boundary** (`toWireContactRows`): `billingName`→`contactBillingName`, `currencyCode`→`currency`, `registrationNumber`→`registrationId`, `notes`→`customerInvoiceNotes`, `shippingAddress`→`deliveryAddress`, `emails: string[]`→`emailList: [{email,label}]`, plus `address`→`addressLine1` inside either address. **Send the TOOL names.** Both addresses require `address` AND `country` — omit either and the API 422s the WHOLE batch, so the client rejects it first with the field named. Note `notes` maps to the customer's DEFAULT INVOICE notes, not an internal memo. **`taxIdType` is not supported** — it appears on no contact definition. All verified live 2026-09-02 with a `taxId` control that stored correctly.
|
|
444
|
+
|
|
445
|
+
137c. **`paymentTerms` is a SILENT ROW-KILL on `bulk_upsert_contacts` and is not exposed by the tool.** The wire shape `customerPaymentTerms: {name, value}` returns HTTP 200 with `status: SUCCESS`, `processedCount: 1`, `failedCount: 0`, `errorDetails: []` — **and the contact is never created.** A scalar returns a plain 400. Verified live twice. Nothing in the job result distinguishes this from a successful import, so a bulk run that sets payment terms silently loses those rows while reporting complete success. Import without terms, then set them per contact. This supersedes any earlier guidance to send `customerPaymentTerms.value`.
|
|
442
446
|
|
|
443
447
|
138. **`get_contact_signals` — read-only contact-history pattern lookup** — `GET /api/v1/contacts/{resourceId}/signals?btType=…` returns the contact's modal patterns (currency, payment-terms, tax-inclusion/presence, top-COA, top-item), cadence (median interval days, days-since-last, interval ratio), and outstanding-balance snapshot for one (contact × business-transaction-type) pair. `btType` is required: `SALE` | `PURCHASE` | `SALE_CREDIT_NOTE` | `PURCHASE_CREDIT_NOTE`. Returns null `data` when sampleSize < 5 or the freshness layer is unavailable. Cache key is per-(contactId, btType) pair, so repeated calls for the same pair are cheap. **Three slices are always empty/null on this endpoint** — `severitySummary`, `outlierFlags`, `revealedDivergences` — because they require a draft to compare against; those populate only on the per-result `contactSignals` object inside `validate_drafts` responses. Use this tool for "what does this contact normally look like?" questions before drafting; use `validate_drafts` for "how does this draft compare to the contact's history?" questions after drafting.
|
|
444
448
|
|