Pulls every connected bank (Plaid/Teller) for the caller's org, maps each…
Pulls every connected bank (Plaid/Teller) for the caller's org, maps each fetched transaction to a posting and books it idempotently, then advances that…
POST /v1/books/bank/sync
| Address | https://api.hanzo.ai/v1/books/bank/sync |
| Method | POST |
| Operation | post_books_bank_sync |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Pulls every connected bank (Plaid/Teller) for the caller's org, maps each fetched transaction to a posting and books it idempotently, then advances that connector's cursor so the next sync resumes where this one stopped. One connector's outage is skipped rather than failing the whole sync. It reports the batch: how many transactions were seen, how many vouchers posted, how many inflows reconciled against the processor clearing account, how many raised a question, how many were own-account transfers, and how many were already-processed no-ops. It is READ-ONLY against the bank — it ingests, it never sends money.
Request
The document declares no body for POST /v1/books/bank/sync. The handler is typed in cloud but its shape is not yet emitted, so the fields are not listed here — ask the MCP door's describe for post_books_bank_sync, which answers from the running route.
Response
| Status | Body | Meaning |
|---|---|---|
200 | BankTally | ok |
200 body — 6 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
ingested | body | integer | — | transactions seen |
posted | body | integer | — | vouchers newly posted (outflow + reconciled) |
questions | body | integer | — | unmatched inflows that raised a question |
reconciled | body | integer | — | inflows cleared against Square-clearing |
skipped | body | integer | — | already-processed idempotent no-ops |
transfers | body | integer | — | own-account moves recorded (no P&L) |
Failure carries the platform error shape — see Errors.
Examples
hanzo books bank syncimport { Configuration, BooksApi } from 'hanzoai';
const api = new BooksApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postBooksBankSync();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import BooksApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = BooksApi(client).post_books_bank_sync()cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.BooksAPI.PostBooksBankSync(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, books_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = books_api::post_books_bank_sync(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.BooksApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new BooksApi(client).postBooksBankSync();curl -X POST https://api.hanzo.ai/v1/books/bank/sync \
-H "Authorization: Bearer $HANZO_API_KEY"The door reaches books through the books tool, which names its 24 operations with its own verbs — this one among them, under a name only the door declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "list_book_accounts"
}
}
}'How is this guide?