{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"2c5e6107-2257-4357-9a20-49803c3534c5","name":"AI Zeny API (Local + Cloud)","description":"**Direct Send policy, 25 October 2026:** This collection has no executable pre-request or test scripts. Pressing Send reaches the configured API endpoint; the server returns its validation or authorization response. Fill required variables and file paths yourself. Older mentions below of Postman confirmation guards, automatic fixture generation, or scripted assertions are superseded. Check the effect label before sending and never blindly retry an uncertain write.\n\n# AI Zeny API (Local + Cloud)\n\n**Start here.** One collection, three top-level paths:\n\n| Folder | Where the request runs | Base URL | Bearer token | PC online? |\n| --- | --- | --- | --- | --- |\n| **Local PC (localhost / LAN)** | Directly on the Windows PC | `{{baseUrl}}` (or its LAN address) | `{{localApiToken}}` | Yes |\n| **Cloud Relay (online PC via Pusher)** | Cloud forwards a supported operation to the PC | `{{cloudBaseUrl}}` | `{{cloudApiToken}}` | Yes |\n| **Cloud Snapshot (server SQLite; PC may be offline)** | Cloud reads its latest available SQLite snapshot | `{{cloudBaseUrl}}` | `{{cloudApiToken}}` | No |\n\nChoose the path by **data source**, not just HTTP method. Local and Relay can contain POST requests that only read data; *(read only)* folders do not change BUSY. **⚠** folders contain actions that can change BUSY or AI Zeny settings and require the one-send `confirmMutating=yes` guard. Voucher **Create** (write) and Voucher **PDFs** (read/print an existing voucher) are separate. Do not automatically retry a write whose outcome is uncertain. Snapshot contains GET requests only and reports its data freshness; an offline PC does not make a snapshot fresher.\n\nThe Local PC path is served by the **AI Zeny Host** Windows service. Local requests use one Local Bearer token except public health; Cloud Relay and Cloud Snapshot use the organization's cloud API token. Never interchange those tokens. The collection contains request definitions, not token values. Select a private Postman environment such as **AI Zeny – Development**; do not share that environment or export its synced secrets to customers. Give customers a separate environment with their own token values.\n\nSource contracts: the Windows Local API documentation and routes, plus the cloud V1 Relay catalogue and Snapshot registry. Keep this collection aligned with them whenever operations, parameters, responses or examples change.\n\n## Before you start\n\n1. The API runs inside the **AI Zeny Host** Windows service. It starts with Windows and the **AI Zeny Recovery** service restarts it by itself if it stops (D42) — no command is needed. If `/api/v1/health` does not answer: wait a minute (AI Zeny may be updating or restarting); if the AI Zeny window says **Local API stopped**, someone stopped it on purpose — press **Start API** there. Otherwise check that `baseUrl` has the right port.\n    \n2. Select the environment **AI Zeny – Development**. `baseUrl` is `http://127.0.0.1:8801` (8801 is the default port; the real port is in `%ProgramData%\\AI Zeny\\local-api.endpoint.json`). From another computer on the same LAN, set `baseUrl` to that PC's LAN address and Local API port, as shown in AI Zeny.\n    \n3. Put the Local PC token into **`localApiToken`** in a private environment. Prefer a local/current-only value; the existing Development environment has a synced secret value, so do not share or export that environment. Get it in AI Zeny: _BUSY Data → Local API → Local API Bearer Token → Reveal / Copy token_ (the GUI must be unlocked with your PIN). The file `%ProgramData%\\AI Zeny\\local-api.token` holds it too (readable by the nominated Windows user only).\n    \n4. Run **Local PC → Health & Status (read only) → Health (public)** first, then **Status**. If Status answers 200, the token and connection are correct.\n    \n\n## Response envelope (every response, since 0.0.7)\n\nEvery JSON response has three top-level members, in this order — plus, on a few successes only, one optional fourth and last member `configuration` (AI Zeny's own saved settings for that data, for example on **List BUSY companies**; never on a failure or an NDJSON line):\n\n``` json\n{ \"success\": true, \"data\": [], \"metadata\": {} }\n\n ```\n\n- `success` — a boolean: `true` only when the request was accepted, validated and completed. An empty result is still `true` (`\"data\": []`).\n    \n- `data` — only the requested data: a list directly as an array (companies, units), one record as an object, `null` on failure.\n    \n- `metadata` — never null (`{}` when empty): pagination, filters, timing (`elapsedMs`), `apiVersion`, `operation`, `requestId`, plan limits, or the error.\n    \n\nHTTP status codes stay meaningful (2xx / 4xx / 5xx). The collection-level test checks the envelope on every response (on an `application/x-ndjson` stream, on every line).\n\n## Authentication\n\nLocal PC uses `Authorization: Bearer {{localApiToken}}` through collection-level auth. Cloud Relay and Cloud Snapshot use request-level Bearer `{{cloudApiToken}}`. `X-Api-Key`, Basic, sessions, cookies and query tokens are refused with `401 UNAUTHORIZED` and `WWW-Authenticate: Bearer`. The Local token is created on the PC and must not be sent as the Cloud token or placed in a URL.\n\n## Network rules\n\n- Accepted only from loopback or a private LAN address (10/8, 172.16/12, 192.168/16, 169.254/16, 100.64/10, fc00::/7, fe80::/10) and with a `Host` that names this PC; otherwise `403 LOCAL_NETWORK_ONLY`. Forwarded headers are never read.\n    \n- Windows Firewall rule _AI Zeny Local API (local network)_: TCP on the Local API port, LocalSubnet, Domain/Private profiles only.\n    \n- Bodies are JSON, at most 16 KiB (`413 REQUEST_TOO_LARGE`); schedule routes and the sales-order create accept 64 KiB, saved-query routes 128 KiB, script and message routes 1 MiB, and a message insert 9 MiB.\n    \n- While the Host stops (for example during an automatic update) new requests get `503 HOST_STOPPING` with `Retry-After: 30`.\n    \n- If the PC's user stopped the Local API in AI Zeny, the port is closed (connection refused) until they press **Start API**. Since D43 only the listener closes: the Host keeps running schedules, the cloud relay and enrollment refresh.\n    \n\n## Errors\n\nEvery error is the envelope with `\"success\": false`, `\"data\": null` and `metadata.error { code, message[, field] }`, plus `metadata.requestId` (the same id as the `X-Request-Id` header) and, on V1 data routes, `metadata.apiVersion`. `field` names the refused request member. Messages are fixed text: no SQL, paths, servers, passwords, tokens or data. Unknown routes: `404 NOT_FOUND`; a version that does not exist: `404 API_VERSION_UNSUPPORTED`.\n\n``` json\n{ \"success\": false, \"data\": null, \"metadata\": { \"error\": { \"code\": \"INVALID_PARAMETER\", \"message\": \"…\", \"field\": \"financialYear\" }, \"requestId\": \"…\", \"apiVersion\": \"v1\" } }\n\n ```\n\n## Environment variables\n\n| Variable | Meaning |\n| --- | --- |\n| `baseUrl` | Local PC base URL, e.g. `http://127.0.0.1:8801` or the PC's LAN address and port |\n| `localApiToken` | Local PC Bearer token. Keep its environment private; do not share or export its synced value |\n| `companyCode` | A configured BUSY company code for the read-only V1 operations, e.g. `COMP0001` (`^[A-Z0-9_-]{1,32}$`) |\n| `financialYear` | Four-digit starting year, e.g. `2026` = April 2026 – March 2027 |\n| `confirmMutating` | Leave empty. `yes` lets one mutating request run (reset automatically after it). |\n| `targetCompanyCode` | The company a mutating BUSY company request acts on. Empty by default. |\n| `masterAccountId` | Test account code set by create account; used by modify account. Leave empty until creation succeeds. |\n| `masterAccountName` | Test account name set by create account; sent as `expectedName` by modify account. |\n| `masterProductId` | Test product code set by create product; used by modify product. Leave empty until creation succeeds. |\n| `masterProductName` | Test product name set by create product; sent as `expectedName` by modify product. |\n| `busySqlPassword` | SQL login password for _create (SQL Server)_ — **current value only**, clear it after use. |\n| `scheduleName` | A schedule's name for the Schedules requests. |\n| `scheduleScriptName` | The saved named script a new schedule runs (use a harmless one when testing). |\n| `scheduleRevision` | The schedule revision you read (set by create and change). |\n| `scheduleRunId` | A history row id (set by _Run history_ and _Run now_). |\n| `messageChannel` | `email` or `whatsapp` (Messages requests; collection default `email`) |\n| `messageId` | A message row id (set by _List messages_ and _Insert_) |\n| `messageRevision` | The row revision you read (set by list, get, insert, update, reconcile) |\n| `cloudBaseUrl` | `https://api.aizeny.com` for Cloud Relay and Cloud Snapshot |\n| `cloudApiToken` | Organization cloud API token for Cloud Relay and Cloud Snapshot; keep private and never use the Local API token here |\n| `salesOrderReference` | A new, unique test reference for **⚠ Voucher Create** (current value only; the request is skipped without one). |\n| `salesOrderId` | Set by the sales-order create test. |\n| `cloudIdempotencyKey` | Set and cleared by the Cloud master-write requests (one key per write; kept after a `504` so a retry reuses it). |\n| `confirmHighImpact` | Leave empty. A **⚠⚠** request (uploads, Google writes, backup and restore, M-PIN recovery) runs only with `confirmMutating = yes` **and** this set to the exact route its pre-request script names; both are cleared after one send. |\n| `sqlCompanyCode` / `sqlFinancialYear` | SQL Server test company COMP0002 / 2026 (the defaults of `companyCode` / `financialYear`). |\n| `accessCompanyCode` / `accessFinancialYear` / `accessCustomerId` / `accessProductId` / `accessSalesInvoiceVoucherId` / `accessSalesInvoiceNumber` | Access test company COMP0001 / FY2026 and its fixtures: copy current values into `companyCode`, `financialYear`, `customerId`, `productId`, `salesInvoiceVoucherId` to test Access. Bounded BUSY writes are supported on Access within each route's documented limits; the four account report-PDF routes still refuse Access with `409 BUSY_REPORT_PROVIDER_UNSUPPORTED`. Use fresh synthetic references for writes and check the route's prerequisites. |\n| `salesInvoiceReference`, `receiptReference`, `returnReference`, `purchaseReference`, `purchaseReturnReference`, `paymentReference` | NEW unique test references for the ⚠ voucher creates (current values only). |\n| `masterAccountGroupId` / `…Name`, `masterProductGroupId` / `…Name`, `lastContactId` | Set by the ⚠ group and contact create requests; used by their modify requests. |\n| `savedQueryPin` / `savedQueryNewPin` | Secret, current value only: a saved query's source PIN (not the PC's M-PIN). |\n| `catalogueTemplateName`, `catalogueNewDesignName`, `catalogueTemplateRevision`, `photoSourceFolder` | Catalogue design and photo-source requests. |\n| `googleExportName` / `googleExportRevision`, `googleAttemptId`, `googleConnectionId`, `googleSpreadsheetId`, `googleSheetId` | Google requests (this PC only). |\n| `backupDriveFileId`, `backupUploadId`, `backupRestoreId`, `backupRecoveryKey` (secret) | Backup and restore requests (this PC only). |\n| `recoveryChannel`, `recoveryCode` (secret), `recoveryNewMpin` (secret) | M-PIN recovery requests (this PC only; a code is a real message). |\n\n**Not included (GUI-internal):** `POST /api/v1/gui/presence`, `/enroll`, `/unlock/verify`, `/unlock/create`, `/unlock/change` — used only by the AI Zeny window. Every other Local API route has a request under **Local PC** (2026-10-18 acceptance audit): the management routes added that day are in the folders *Catalogue Designs & Photo Sources*, *Upload, Google & Backup Status*, and the ⚠ folders *Cloud Data Upload*, *Google*, *Backup & Restore* and *Security & Subscription*.\n","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"16351567","team":2097166,"collectionId":"2c5e6107-2257-4357-9a20-49803c3534c5","publishedId":"2sBYHRVMN3","public":true,"publicUrl":"https://documenter-api.postman.tech/view/16351567/2sBYHRVMN3","privateUrl":"https://go.postman.co/documentation/16351567-2c5e6107-2257-4357-9a20-49803c3534c5","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":"Explore AI Zeny’s APIs for BUSY Accounting software, with documentation and examples for accounts, products, reports, voucher PDFs and sales orders."},{"name":"title","value":"BUSY Accounting Software API Collection | AI Zeny"}],"appearance":{"default":"light","themes":[{"name":"dark","logo":null,"colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"FF6C37"}},{"name":"light","logo":null,"colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"}}]}},"version":"8.12.10","publishDate":"2026-10-14T06:49:27.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"BUSY Accounting Software API Collection | AI Zeny","description":"Explore AI Zeny’s APIs for BUSY Accounting software, with documentation and examples for accounts, products, reports, voucher PDFs and sales orders."},"logos":{"logoLight":null,"logoDark":null}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/d498afad2bb1bf627e130d3214a36868e5bfc599761e4dd3129c01defc71a9dd","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/2sBYHRVMN3"}