# toknzer · Invoice Generator

> A static, client-side invoice editor at https://toknzer.com/invoices/. It creates,
> edits and exports invoices entirely in the browser — no server, no login, no
> tracking. Invoices are stored locally (IndexedDB) using the documented JSON
> document format below, which agents and local MCP servers can produce and consume.

## How an agent uses this tool

There is no hosted API. The interoperable surface is the **invoice document**: a
plain JSON object validated by the published schema. A typical agent flow:

1. Build an invoice document that conforms to
   [invoice.schema.json](https://toknzer.com/invoices/invoice.schema.json).
2. Validate it (any JSON Schema 2020-12 validator).
3. Hand it off — e.g. write it to the user's `toknzer` IndexedDB via a local MCP
   server / browser automation, or render/export it with the same fields.

See [invoice.example.json](https://toknzer.com/invoices/invoice.example.json) for a
complete, valid document.

## Document format (summary)

Top-level fields (all strings unless noted; empty string means "omit"):

- `v` (number): format version, currently `2`.
- `currency`: ISO 4217 code, e.g. `USD`, `EUR`, `JPY`. Supported codes are listed in
  the schema's `enum`.
- `label`: heading text, e.g. `INVOICE`.
- `num`: invoice number, e.g. `INV-0001`.
- `date`, `due`: ISO `YYYY-MM-DD`.
- `terms`: payment terms label, e.g. `Net 30`.
- `po`: purchase-order reference.
- `from`, `billto`, `shipto`: multi-line party blocks (use `\n` for new lines).
- `rows`: array of line items, each `{ "d": description, "q": quantity, "r": rate }`
  where `q` and `r` are numeric strings.
- `disc`, `tax`: percentages (numeric strings).
- `ship`, `paid`: amounts (numeric strings).
- `notes`, `terms2`: free-text footer blocks.

## Totals (how the tool computes them)

- `subtotal   = Σ (q × r)`
- `discount   = subtotal × disc%`
- `tax        = (subtotal − discount) × tax%`
- `total      = subtotal − discount + tax + ship`
- `balanceDue = total − paid`

Amounts render with the currency symbol; `JPY` and `KRW` use 0 decimal places, all
others use 2.

## Constraints

- Everything is client-side and free; no auth, no telemetry, no rate limits.
- The format is intentionally compact and stable. `localStorage`/IndexedDB keys are
  fixed for backwards compatibility — do not invent new ones.
