Install
$ agentstack add skill-teamtinvio-jaz-ai-api ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Jaz API Skill
You are working with the Jaz REST API — the accounting platform backend. Also fully compatible with Juan Accounting (same API, same endpoints).
Pick the right invocation path first
Before touching this skill's HTTP details, check what's actually available:
- Running inside an MCP host (Claude Desktop, Cowork): use the MCP tools (
execute_toolwithcreate_invoice,list_bills, etc.). Do not write direct HTTP. The MCP server handles auth, retries, and field shape for you. - Running Claude Code with the
jaz-clioCLI: use the CLI commands (clio invoices list --json, etc.). Same code path, structured output. - No agent surface, raw integration: write HTTP calls per the endpoints catalog below.
The rest of this skill — field names, gotchas, error catalog, dependency order, search filter syntax — applies regardless of invocation path. Read it for context, not for HTTP-call construction unless you're in the third bucket.
Reading Order
Core fundamentals (read first, every integration): Identifiers & Dates 1–3; Names & Fields 9–13; Transaction Creation 14–16; Chart of Accounts 17–22; Payments / Cross-Currency 4–8; Journals & Cash 23–26; Credit Notes & Refunds 27–28; Reports 36–37; Tax Profile Scoping 100; Transaction References 104; Draft Finalization Pipeline 81–88; Jaz Magic / PDF-JPG 57–63; Currency Rates 39, 49, 105; Withholding Tax 45, 98.
Integration depth (API clients, pipelines, batch jobs, MCP/CLI): Bulk Upsert (Items/Contacts/Rates); Background Jobs (filter resourceId not jobId); Export Records; Pagination (38); Search & Filter (50–56); Response Shape Gotchas (66–73); Cash Entry Response Shape (74–77); Entity Resolution (78–80); Bank Rules (89–90c); Fixed Assets (91–92c); Subscriptions & Scheduled (93–94); niche endpoints (95–102); Journals balance (103); Quick Fix (107, 111); TTB (108); Dynamic Strings (109–110); Sub-Resource Shapes (112); Nano-Classifier (113); Scheduler Asymmetry (114); Payment Record CRUD (115–117); Bulk Upserts transactions (118–122); Reconciliation write-side (123–127); Drafts lifecycle (128–135); Orders — Sale Quotes / Sale Orders / Purchase Requests / Purchase Orders (references/orders.md); Claims — records / lifecycle / bulk + conversion + payouts + Employees + Claim Settings (references/claims.md).
When to Use This Skill
- Writing or modifying any code that calls the Jaz API
- Building API clients, integrations, or data pipelines
- Debugging API errors (422, 400, 404, 500)
- Adding support for new Jaz API endpoints
- Reviewing code that constructs Jaz API request payloads
Quick Reference
Base URL: https://api.getjaz.com Auth: x-jk-api-key: header on every request — key has jk- prefix (e.g., jk-a1b2c3...). NOT Authorization: Bearer or x-api-key. Content-Type: application/json for all POST/PUT/PATCH (except multipart endpoints: createBusinessTransactionFromAttachment FILE mode, importBankStatementFromAttachment, and attachment uploads) All paths are prefixed: /api/v1/ (e.g., https://api.getjaz.com/api/v1/invoices)
Critical Rules
Identifiers & Dates
- All IDs are
resourceId— neverid. References useResourceIdsuffix. - All transaction dates are
valueDate— notissueDate,invoiceDate,date. This is an accounting term meaning "date of economic effect." - All dates are
YYYY-MM-DDstrings — ISO datetime and epoch ms are rejected.
Payments (Cross-Currency Aware)
- Payment amounts have two fields:
paymentAmount= bank account currency (actual cash moved),transactionAmount= transaction document currency (invoice/bill/credit note — amount applied to balance). For same-currency, both are equal. For FX (e.g., USD invoice paid from SGD bank at 1.35):paymentAmount: 1350(SGD),transactionAmount: 1000(USD). - Payment date is
valueDate— notpaymentDate, notdate. - Payment bank account is
accountResourceId— notbankAccountResourceId. - Payments require 6 fields:
paymentAmount,transactionAmount,accountResourceId,paymentMethod,reference,valueDate. - Payments wrapped in
{ payments: [...] }— array recommended. Flat objects are now auto-wrapped by the API, but array format is preferred for clarity.
Names & Fields
- Line item descriptions use
name— notdescription. - Item names: canonical field is
internalName, butnamealias is accepted on POST. GET responses return bothinternalNameandname. - Tag names: canonical field is
tagName, butnamealias is accepted on POST. GET responses return bothtagNameandname. - Custom field names: POST uses
name, GET returns bothcustomFieldNameandname. - Invoice/bill number is
reference— notreferenceNumber.
Transaction Creation
saveAsDraftdefaults tofalse— omitting it creates a finalized transaction. Explicitly sendingsaveAsDraft: truecreates a draft.- If
saveAsDraft: false(or omitted), every lineItem MUST haveaccountResourceId. - Phones MUST be E.164 —
+65XXXXXXXX(SG),+63XXXXXXXXXX(PH). No spaces.
Chart of Accounts
- Tax profiles pre-exist — NEVER create them. Only GET and map.
- Bank accounts are CoA entries with
accountType: "Bank Accounts". A convenience endpointGET /bank-accountsexists but returns a flat array[{...}]— NOT the standard paginated{ data, totalElements, totalPages }shape. Normalize before use. - CoA bulk-upsert wrapper is
accounts— notchartOfAccounts. - CoA POST uses
currency— notcurrencyCode. (Asymmetry — GET returnscurrencyCode.) - CoA POST uses
classificationType— GET returnsaccountType. Same values. Both fields accept the classic 12 types (Bank Accounts, Cash, Current Asset, Fixed Asset, Inventory, Current Liability, Non-current Liability, Shareholders Equity, Operating Revenue, Other Revenue, Operating Expense, Direct Costs) AND the IFRS 18 set added 2026-04 (Discontinued Expense, Discontinued Income, Finance Cost, Financing Income, Goodwill, Income Tax Expense, Investing Expense, Investing Income, Investment) — see rule 140 for IFRS 18 detail. - CoA code mapping: match by NAME, not code — pre-existing accounts may have different codes. Resource IDs are the universal identifier.
Bulk Upsert (Items, Contacts & Rates)
- Items bulk-upsert (
POST /items/bulk-upsert) — max 500 per call. ProvideresourceIdper item to update (partial — only changed fields needed, server preserves existing values). OmitresourceIdto create (defaults:status=ACTIVE,itemCategory=NON_INVENTORY). Response:{ resourceId: null, resourceIds: [...] }. SYNC — returns resourceIds immediately. - Contacts bulk-upsert (
POST /contacts/bulk-upsert) — max 500 per call. ProvideresourceIdto update (partial), omit to create.billingNamerequired for create. ASYNC — returns{ jobId, status: "QUEUED", totalRecords }. Pollsearch_background_jobswithfilter: {resourceId:{eq:jobId}}until status isSUCCESS,FAILED, orPARTIAL_SUCCESS. Unlike items, contacts bulk-upsert is asynchronous. - Rates bulk-upsert (
POST /organization/currencies/rates/bulk-upsert) — max 500 per call. RequiresrateDirectionper rate (FUNCTIONAL_TO_SOURCEorSOURCE_TO_FUNCTIONAL). Auto-enables currencies not yet enabled in the org — no need to calladd_currencyfirst. Response:{ resourceId: null, resourceIds: [...] }.
Background Jobs (Universal Async Tracking)
- ANY operation that returns a
jobIdcan be polled viasearch_background_jobs. This includes: contacts bulk-upsert (UPSERT_CONTACTS), items bulk-upsert (UPSERT_ITEMS), bank statement import (PROCESS_BANK_STATEMENT_FILES), and magic processing (MAGIC_TRANSACTION_*). - 🚨 CRITICAL: Filter by
resourceId, NOTjobId—filter: {jobId:{eq:...}}is silently ignored (returns ALL jobs). Must usefilter: {resourceId:{eq:theJobId}}. The response field is namedjobIdbut the filter path isresourceId. - Poll until terminal status —
SUCCESS,FAILED, orPARTIAL_SUCCESS. UseprocessedCount,failedCount,totalRecordsfor progress.PARTIAL_SUCCESSmeans some records succeeded and some failed — checkerrorDetailsarray for per-record errors. startedAtfilter does NOT work — usecreatedAtfor date range filtering.errorDetailsis[](empty array) on success — notnull.- Known jobTypes:
UPSERT_CONTACTS,UPSERT_ITEMS,PROCESS_BANK_STATEMENT_FILES,MAGIC_TRANSACTION_PURCHASE,MAGIC_TRANSACTION_SALE,MAGIC_TRANSACTION_SALE_CREDIT_NOTE.
Export Records
outputFormat: "XLSX"is always required — no other format is currently supported. Hardcode it.query+filterare mutually exclusive — the server returnsINVALID_SEARCH_INPUTif both are provided. Passquery(structured search string, same syntax as dashboard) ORfilter(raw JSON filter object), never both.- Available entity types:
INVOICE,BILL,CUSTOMER_CREDIT_NOTE,SUPPLIER_CREDIT_NOTE,SALE_PAYMENT,PURCHASE_PAYMENT,BATCH_PAYMENT,CONTACT,ITEM,CAPSULE,SCHEDULED_TRANSACTION,JOURNAL,BANK_RECORD,CASHFLOW_TRANSACTION,FIXED_ASSET,CHART_OF_ACCOUNT,TAX_PROFILE. fileUrlexpires in ~5 minutes — it's a pre-signed S3 URL. Warn the user to download immediately.- Preview first — use
preview_export_recordsto confirm scope (count + sample rows) before callingexport_records. ThefilterDescriptionfield gives a human-readable summary like"2580 records | Status in: UNPAID". - Column customization — use
get_export_columnsto discover available column paths and headers. Pass acolumnsarray to select specific fields. Omit for default columns. previewRowskeys are column headers — not field paths. E.g.{"Invoice Ref #": "INV-001", "Customer": "Acme"}. UseresolvedColumnsto map headers back to paths.
Journals & Cash
- Journals use
journalEntrieswithamount+type: "DEBIT"|"CREDIT"— NOTdebit/creditnumber fields. - Journals support multi-currency via
currencyobject — same format as invoices/bills:"currency": { "sourceCurrency": "USD" }(auto-fetch platform rate) or"currency": { "sourceCurrency": "USD", "exchangeRate": 1.35 }(custom rate). Must be enabled for the org. Omit for base currency. Three restrictions apply to foreign currency journals: (a) no controlled accounts — accounts withcontrolFlag(AR, AP) are off-limits (use invoices/bills instead), (b) no FX accounts — FX Unrealized Gain/Loss/Rounding are system-managed, (c) bank accounts must match — can only post to bank accounts in the same currency as the journal (e.g., USD journal → USD bank account only, not SGD bank account). All other non-controlled accounts (expenses, revenue, assets, liabilities) are available. currencyobject is the SAME everywhere — invoices, bills, credit notes, AND journals all usecurrency: { sourceCurrency: "USD", exchangeRate?: number }. Never usecurrencyCode: "USD"(silently ignored on invoices/bills) orcurrency: "USD"(string — causes 400 on invoices/bills).- Cash entries use
accountResourceIdat top level for the BANK account +linesarray for offsets.
Credit Notes & Refunds
- Credit note application wraps in
creditsarray withamountApplied— not flat. - CN refunds use the same Payment shape as invoice/bill payments —
paymentAmount,transactionAmount,accountResourceId,paymentMethod,valueDate,reference. The API also accepts aliasesrefundAmount/refundMethod(see Rule 53) but prefer canonicalpaymentAmount/paymentMethodfor consistency.
Inventory Items
- Inventory items require:
unit(e.g.,"pcs"),costingMethod("FIXED"or"WAC"),cogsResourceId,blockInsufficientDeductions,inventoryAccountResourceId.purchaseAccountResourceIdMUST be Inventory-type CoA. - Delete inventory items via
DELETE /items/:id— not/inventory-items/:id.
Cash Transfers
- Cash transfers use
cashOut/cashInsub-objects — NOT flatfromAccountResourceId/toAccountResourceId. Each:{ accountResourceId, amount }.
Schedulers
- Scheduled invoices/bills wrap in
{ invoice: {...} }or{ bill: {...} }— not flat. Recurrence field isrepeat(NOTfrequency/interval).saveAsDraft: falserequired.referenceis required inside theinvoice/billwrapper — omitting it causes 422. - Scheduled journals use FLAT structure with
schedulerEntries— not nested injournalwrapper.valueDateis required at the top level (alongsidestartDate,repeat, etc.).
Bookmarks
- Bookmarks use
itemsarray wrapper withname,value,categoryCode,datatypeCode.
Custom Fields
- Do NOT send
appliesToon custom field POST — causes "Invalid request body". Only sendname,type,printOnDocuments.
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. 35b. Custom field search: POST /custom-fields/search with filter/sort/limit/offset. Filter by customFieldName (StringExpression), datatypeCode (StringExpression: TEXT, DATE, DROPDOWN). 35c. Custom field GET: GET /custom-fields/:resourceId returns full definition including applyToSales, applyToPurchase, applyToCreditNote, applyToPayment, printOnDocuments, listOptions.
Tags on Transactions
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 (singular, wrapped to array). API accepts the array directly.
Nano Classifiers
35e. ClassifierConfig on line items: classifierConfig: [{ resourceId: "", type: "invoice"|"bill", selectedClasses: [{ className: "Class A", resourceId: "" }], 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.
Reports
- Report field names differ by type — this is the most error-prone area:
| Report | Required Fields | |--------|----------------| | Trial balance | startDate, endDate | | Balance sheet | primarySnapshotDate | | P&L | primarySnapshotDate, secondarySnapshotDate | | General ledger | startDate, endDate, groupBy: "ACCOUNT" (also TRANSACTION, CAPSULE) | | Cashflow | primaryStartDate, primaryEndDate | | Cash balance | reportDate | | AR/AP report | endDate | | AR/AP summary | startDate, endDate | | Bank balance summary | primarySnapshotDate | | Equity movement | primarySnapshotStartDate, primarySnapshotEndDate | | Ledger highlights | (none — simple GET) |
- Ledger highlights is a simple GET —
GET /api/v1/ledger/highlightsreturns org-wide GL summary metadata: transaction counts by type, date range, active accounts/currencies, cross-currency flag, and dynamic FX types. No parameters. Response dates are epoch ms (see Rule 52).
37a. Data exports use simpler field names: P&L export uses startDate/endDate (NOT primarySnapshotDate). AR/AP export uses endDate.
Pagination
- All list/search endpoints use
limit/offsetpagination — NOTpage/size.offsetis a 0-indexed PAGE NUMBER, not a row-skip (offset=1 = second page oflimitrows). Default limit=100, offset=0. Max limit=1000, max offset=65536.page/sizeparams are silently ignored. Response shape:{ totalPages, totalElements, truncated, data: [...] }. When `trunc
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: teamtinvio
- Source: teamtinvio/jaz-ai
- License: MIT
- Homepage: https://www.jaz.ai
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.