Create book

Posts a reviewed scanned bill to the ledger.

POST /v1/books/scan/book

Addresshttps://api.hanzo.ai/v1/books/scan/book
MethodPOST
Operationpost_books_scan_book
AuthAuthorization: Bearer $HANZO_API_KEY

Posts a reviewed scanned bill to the ledger. It is the scanner's ONLY write: the voucher goes through the same post() choke point every other source uses, so it is checked to balance (Σdebit == Σcredit) and is idempotent by (scan, scanId) — re-booking the same scan answers posted=false and writes nothing. A bill whose economic identity (vendor, total, issue date) already posted under a DIFFERENT scan is refused 409 unless override is set, which is what stops the same receipt re-scanned into a new file hash from double-booking. An unbalanced voucher is refused 400.

Request

11 fields, body application/json (required).

FieldInTypeRequiredDescription
overridebodyboolean—Override books this bill even when one of the SAME economic identity (vendor, total, issue date) already posted — the explicit human confirmation that a same-looking bill is a genuine second spend, not the same receipt re-scanned.
scanIdbodystring—ScanID is the scanned document's file hash, as GET /v1/books/inbox and the scan draft report it.
voucherbodybooks.Voucher—
voucher.descriptionbodystring—Description is the human line for the event, e.g. the vendor a bill came from.
voucher.legsbodybooks.Leg[]—Legs are the sides of the posting.
voucher.legs[].accountbodystring—Account is the chart-of-accounts number this side posts to, e.g. "5300".
voucher.legs[].creditbodyinteger (int64)—Credit is the leg's credit in exact cents.
voucher.legs[].debitbodyinteger (int64)—Debit is the leg's debit in exact cents.
voucher.postingAtbodystring—PostingAt is the RFC3339 instant the event posts at — the time every statement window filters on.
voucher.sourceIdbodystring—SourceID is the source event's own id within that namespace.
voucher.sourceKindbodystring—SourceKind is the idempotency namespace naming what booked this, e.g. "scan".

Response

StatusBodyMeaning
200books.BookResponseok
defaultproblem-detailsrefused

200 body — 2 fields.

FieldInTypeAlwaysDescription
postedbodyboolean—Posted is true when this call wrote the voucher, false when the same scan had already booked and nothing was written.
scanIdbodystring—ScanID echoes the scan that was booked.

Failure carries the platform error shape — see Errors.

Examples

hanzo books scan book
import { Configuration, BooksApi } from 'hanzoai';

const api = new BooksApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postBooksScanBook({ override: false, scanId: "<scanId>" });
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_scan_book(override=False, scan_id="<scanId>")
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.BooksAPI.PostBooksScanBook(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::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_scan_book(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.BooksApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new BooksApi(client).postBooksScanBook();
curl -X POST https://api.hanzo.ai/v1/books/scan/book \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "override": false,
       "scanId": "<scanId>"
     }'

MCP reaches books through the books tool, which names its 20 operations with its own verbs — this one among them, under a name only MCP 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"
         }
       }
     }'

Books API · All Hanzo APIs · Interactive reference

Was this page useful?