An invoice is data
One validated schema powers the web, automation and every output.
In Invoicey, an invoice is a validated data structure. PDF, ISDOC and payment QR are outputs of the same source data.
One schema, every surface
InvoiceSchema is the shared Zod schema used by the web form, MCP tools,
Slack agent and output renderers.
The result: every surface creates the same kind of invoice. A missing DUZP, malformed IČO or invalid due date is rejected with a specific error that a person or assistant can correct.
The shape
const InvoiceSchema = z.object({
meta: InvoiceMetaSchema, // doc type, number, dates, currency
issuer: IssuerSnapshotSchema, // who is invoicing — frozen at issue
client: ClientSnapshotSchema, // who is billed — frozen at issue
vat: InvoiceVatSchema, // VAT mode and cross-border flags
payment: PaymentSchema, // bank account, symbols, method
items: z.array(InvoiceItemSchema).min(1),
totals: TotalsSchema, // per-rate breakdown and grand total
notes: z.string().max(2000).optional(),
customization: InvoiceCustomizationSchema.optional(),
});Field-by-field detail is in the schema reference.
Validation is strict on purpose
The schema encodes the domain rules that protect issued invoices:
| Rule | Enforced |
|---|---|
| IČO is exactly 8 digits | /^\d{8}$/ |
DIČ is CZ + 8–10 digits | /^CZ\d{8,10}$/ |
| PSČ is 5 digits | /^\d{3} ?\d{2}$/ |
Bank account is prefix-number/bankCode | /^(?:\d{1,6}-)?\d{1,10}\/\d{4}$/ |
| IBAN is Czech | /^CZ\d{22}$/ |
| Due date is not before the issue date | cross-field check |
| Credit notes reference the corrected invoice | conditional requirement |
| At least one line item | .min(1) |
Callers may apply explicit defaults before validation. The parser never guesses a required value.
This bites when automating
An automated call that omits duzp fails validation instead of silently
choosing today's date. Include every required field in create_invoice.
Totals are computed, then verified
Totals are derived from quantity, unit price and VAT rate. At issue time, Invoicey recomputes them server-side and rejects a mismatch.
Currency and language
The schema currently supports Czech invoices in CZK and cs. Multi-currency and translated
invoices require additional tax, exchange-rate and legal-note handling and are not yet supported.