The Tallystick API
POST an invoice, get it back as JSON, as a target format's XML, as a PDF, or as an Excel workbook, or have it checked against a target before you send it anywhere. One key, no SDK, nothing to install. The API runs on the same readers and the same writers as every tool on this site, and an agent can reach the same four tools without any HTTP at all through the hosted MCP endpoint.
Authentication
Every call carries your key in the x-tallystick-key header. API access comes with Tallystick Pro and Team; the key is the same one the tools and the MCP server use. A call without a key answers 401, a call with a key that has no active subscription or trial answers 402 with the plan and reason named.
POST /api/v1/convert
The body is the invoice file itself, exactly as you received it. What comes back follows the query string. With no parameters it is the format the reader recognised plus the invoice as structured JSON: parties, lines, totals, VAT per rate, payment terms.
curl -X POST https://tally-stick.com/api/v1/convert -H "x-tallystick-key: TS-XXXX-XXXX-XXXX-XXXX" --data-binary @invoice.xml
{
"format": "ubl",
"profile": "Peppol BIS Billing 3.0",
"docType": "Invoice",
"invoice": {
"number": "2026-11-05",
"issueDate": "2026-11-05",
"currency": "EUR",
"seller": { "name": "...", "vat": "..." },
"buyer": { "name": "...", "vat": "..." },
"lines": [ { "desc": "...", "qty": 10, "unitPrice": "50.00", "taxCategory": "S" } ],
"totals": { "lineTotal": "500.00", "tax": "100.00", "payable": "600.00" }
}
}
File outputs
Three query parameters turn the same call into a file:
curl -X POST "https://tally-stick.com/api/v1/convert?as=xml&target=xrechnung" -H "x-tallystick-key: TS-XXXX-XXXX-XXXX-XXXX" --data-binary @invoice.xml
as=xml&target=<id>writes the invoice in that target:xrechnung,peppol-bis,nlcius,en16931,zugferd,factur-x,ksef,fatturapa,facturae. The XML is written by the same writers the site's pages use, and a target whose rules the invoice does not satisfy answers422withvalidation_failedand the reasons named, the same list the page shows.as=pdfwrites the readable invoice as a PDF/A-3B carrying the same data as an EN 16931 CII attachment, the same object the pages' PDF button produces.as=xlsxwrites the workbook the site's Excel export writes: anInvoicesheet with the invoice header, parties and totals, and aLinessheet with one row per line item, the same columns the excel-to pages read back. Add&name=<text>(up to 120 characters) to name the downloaded file instead of the invoice number.
Every file answer carries content-disposition with the same name the tools would suggest. Field names in the JSON are the ones the site's own tools work from, so a response can be checked by hand against any page here.
POST /api/v1/detect
The same request, a smaller answer: which format the bytes carry, which profile, and whether this endpoint reads them. Useful for routing before you commit to a parse.
POST /api/v1/validate
A verdict instead of a file. The body is the invoice as before; the query names the scope. With ?target=<id> the answer is that one target's verdict: valid true, or false with the same reasons list a convert call would refuse with. With no target every writable target is checked at once, and passing names the ids that would take the invoice.
curl -X POST "https://tally-stick.com/api/v1/validate?target=peppol-bis" -H "x-tallystick-key: TS-XXXX-XXXX-XXXX-XXXX" --data-binary @invoice.xml
Valid means the target's own validator accepts the invoice, so the write will succeed and the file a recipient receives will pass that format's gate. It is not a claim of full EN 16931 Schematron conformance.
The hosted MCP endpoint
Agents connect without installing anything. Point a client that speaks remote MCP at https://tally-stick.com/mcp/v1; it registers itself, a browser window opens once to take your Pro or Team key, and the tools appear: detect_invoice_format, read_invoice, validate_invoice, convert_invoice. The connect flow is standard OAuth, so agents with one-click connectors can be switched on like any other integration. Connection details are on the MCP page.
Formats
Read today: UBL 2.1 (XRechnung, Peppol BIS, NLCIUS, PINT), UN/CEFACT CII (ZUGFeRD, Factur-X XML), FatturaPA, Facturae, KSeF FA(3), Comarch ERP Enterprise, ANSI X12 and UN/EDIFACT. Written as outputs: the nine target XMLs above, PDF and Excel. A PDF or an Excel workbook sent as input is named by detect and refused by convert with unsupported_format: those containers are opened in the browser tools or through the MCP server, which run the readers a Worker cannot.
Limits
A Pro or Team key gets up to 500 calls per day, the same ceiling a Pro drop carries, and 2 MB per file. A trial key works inside the free fair-use allowance: 10 calls on the day the trial starts, then 5 a day, over the same endpoints. The counter is shared by the API endpoints and the hosted MCP tools: a validate call is one call no matter how many targets it checks. Each API answer carries x-ratelimit-limit and x-ratelimit-remaining; past the ceiling the endpoint answers 429 until the next day. The counter is fair-use accounting, not an exact ledger: two calls in the same millisecond can both pass.
Errors
400 empty body, as=xml without a target, or an unknown as · 401 missing key · 402 no active subscription · 413 file over 2 MB · 422 unreadable, unsupported input format, unknown target, or the target's rules refused the invoice (validation_failed, reasons listed) · 429 daily ceiling reached. Every error body is JSON and names an error code from this list.
What the API stores
The invoice you send is parsed in memory and dropped when the response is written. Nothing is kept, nothing is logged beyond the daily counter, and the key in the header never appears in a URL.
Starting
Start a Pro subscription or a free trial on the pricing page; the key arrives with it. For reading invoices from a local folder with an AI agent instead, the MCP server covers the same formats without the network.