# SendStructured — instructions for AI agents

Last updated: 2026-09-12. Beta.

## What this service does

Converts an invoice into a valid structured e-invoice and validates it with the official validator.
Inputs: a PDF invoice (if it carries embedded Factur-X/ZUGFeRD XML that is used directly), an existing
e-invoice XML file (UBL or CII, e.g. to convert ZUGFeRD to XRechnung or Peppol), pasted invoice text, or
invoice data typed into a form (or JSON via the API).
Outputs, per conversion: XRechnung 3.0 (UBL), Peppol BIS Billing 3.0 (UBL), Factur-X / ZUGFeRD
(CII XML and, when a PDF was uploaded, the hybrid PDF/A-3). Each output comes with a verdict from the
KoSIT validator and, on failure, the rule ids and a plain-English fix.

## Current limitations (beta) — tell the user these

1. **A human must sign in by email.** Generation requires an account; sign-in is a one-time link sent
   to an email address. There is no keyless API and no automated sign-up. An agent cannot complete
   sign-in on its own unless it has access to the user's mailbox.
2. **The free allowance is 10 conversions per account, and no card is required to sign up.** Paid
   plans are pre-orders only; no payment details are taken and nothing is charged during the beta.
3. **Peppol delivery is not live.** The "Send via Peppol" button only records interest. The user
   should email the downloaded XML to their customer's accounts address (or upload it to the
   customer's portal) for now.
4. **The user is responsible for checking the review page.** Extraction can misread PDFs, especially
   line items on non-tabular layouts; the review form exists so a person confirms the data.

## Option A — relay instructions to the user (no computer use)

Tell the user, in this order:

1. Go to https://sendstructured.com/convert and upload the PDF invoice they already send (or paste
   its text, or choose "Fill in the details myself").
2. On the "Check the details" page, correct anything highlighted, and add the fields a PDF usually
   lacks: the customer's electronic address (their accounts email is fine), a buyer reference
   (for German public bodies the Leitweg-ID; otherwise the customer's reference or VAT number), and
   for XRechnung a seller contact name, phone and email. Set the VAT category on each line
   (S standard, Z zero, E exempt, AE reverse charge, K intra-community, G export).
3. Tick the formats needed (Germany: XRechnung or Factur-X; France: Factur-X; Belgium and most of
   the EU: Peppol BIS) and click "Generate and validate".
4. Enter an email address, open the sign-in link from the inbox, and the results page appears.
5. Download the XML (and the hybrid PDF for Factur-X). If a format shows errors, follow the
   per-rule fix links back to the form and regenerate.

## Option B — computer use (drive the site in a browser)

All controls have stable `id` attributes and visible labels. Use them rather than screen positions.

Page `/convert`:
- File input `#file` (accepts application/pdf, max 15 MB) inside form `#upload-form`; submit with `#upload-submit`.
- Or textarea `#invoice-text` in `#text-form`, submit `#text-submit`.
- Or `#blank-submit` to start from an empty form.
- After submit the browser is redirected to `/review/<job-id>`.

Page `/review/<job-id>` (form `#review-form`):
- Document fields: `#number`, `#issue_date` (YYYY-MM-DD), `#due_date`, `#currency` (ISO 4217), `#type_code` (380 invoice / 381 credit note), `#buyer_reference`, `#order_reference`, `#note`.
- Seller fields: `#seller.name`, `#seller.trading_name`, `#seller.street`, `#seller.city`, `#seller.postcode`, `#seller.country` (ISO 3166-1 alpha-2), `#seller.vat_id`, `#seller.registration_id`, `#seller.contact_name`, `#seller.contact_phone`, `#seller.contact_email`, `#seller.electronic_address`, `#seller.electronic_scheme` (EM for email).
- Buyer fields: `#buyer.name`, `#buyer.street`, `#buyer.city`, `#buyer.postcode`, `#buyer.country`, `#buyer.vat_id`, `#buyer.electronic_address`, `#buyer.electronic_scheme`.
- Lines (0-based index i): `#line.i.description`, `#line.i.quantity`, `#line.i.unit` (C62 piece, HUR hour, DAY day…), `#line.i.unit_price` (net), `#line.i.vat_category`, `#line.i.vat_rate`. Two empty rows are always present for new lines.
- `#vat_exemption_reason` (required for categories E, AE, K, G, O).
- Payment: `#payment.means_code` (58 SEPA transfer, 30 transfer, 48 card, 10 cash), `#payment.iban`, `#payment.bic`, `#payment.account_name`, `#payment.terms`, `#payment.remittance_info`.
- Format checkboxes: `#fmt_xrechnung`, `#fmt_peppol`, `#fmt_facturx`. Submit: `#generate`.
- Validation problems are listed in a `.errors` box at the top with the field each refers to; fields with problems carry class `err`, low-confidence extracted fields carry class `low`.

Sign-in (shown after `#generate` if not signed in): form `#login-form`, field `#email`, submit `#login-submit`.
The page then says "Check your email". The human must open the link; it is single-use and valid for one
hour. If the server is a development instance without email, the link is shown on the page as `#dev-signin-link`.

Page `/result/<job-id>`:
- One card per format: `#output-xrechnung`, `#output-peppol`, `#output-facturx`, each with attributes `data-format` and `data-status` (`accept`, `reject`, `unavailable`).
- Downloads: `#download-<format>-xml`, `#download-facturx-pdf` (hybrid PDF, when available), `#report-<format>` (validator report XML).
- Failed rules appear in a table inside the card with a "Fix" link back to the field.
- `#edit-invoice` returns to the review form; `#send-peppol` records interest only (see limitations).
- Survey buttons: `#answer-yes`, `#answer-not-yet`, `#answer-receiving` — answer on the user's behalf only if they told you.

Other pages: `/pricing` (form `#preorder-form`: `#email`, `#plan`, `#pre-xrechnung`, `#pre-peppol`, `#pre-facturx`, `#pre-ksef`, `#note` (optional: customer countries only, never company names), submit `#preorder-submit`), `/api-keys` (signed-in only: `#issue-api-key`, key shown once in `#api-key-value`), `/login`, `/guide`, `/privacy`, `/terms`. Navigation links: `#nav-convert`, `#nav-pricing`, `#nav-guide`, `#nav-api-docs`, `#nav-agents`, `#nav-signin`, `#nav-api-key`, `#nav-signout`.

Do not: submit the review form with invented VAT numbers, IBANs or addresses; answer the survey or
pre-order without the user's instruction; retry sign-in links (they are single-use).

## Option C — JSON API (preview — not production-ready yet; needs a key)

A signed-in human issues a key at `/api-keys`. Then:

    GET  /api/v1/example                          -> a complete sample request body
    POST /api/v1/convert      (header X-API-Key)  -> {"ok": bool, "id": ..., "outputs": {"<format>": {"xml": ..., "validation": {"status", "scenario", "errors": [{"rule","message"}], "warnings": [...]}}}}
    POST /api/v1/extract      (multipart "file")  -> {"invoice": {...}, "confidence": {...}, "extractor": "heuristic"|"claude"}   (PDF in, canonical JSON out; nothing generated)
    POST /api/v1/convert-pdf  (multipart "file", form field "formats"="xrechnung,peppol,facturx") -> as /convert plus "invoice" (what was extracted) and, for facturx, "pdf_base64" (the hybrid PDF)

Body for /convert: `{"invoice": {...canonical invoice...}, "formats": ["xrechnung","peppol","facturx"]}`.
A 422 response lists missing mandatory fields as `{"field","message"}` — for /convert-pdf it also returns the extracted
`invoice` so the caller can fill the gaps and resubmit to /convert. Extraction is best-effort; a human should check it.
Schema on `/docs`.
The same 10-conversion allowance applies to API calls on the free tier.

## Roadmap for agents (not yet available)

Keyless trial API, an MCP server exposing `convert_invoice` and `validate_einvoice`, a downloadable
skill file, and structured metadata on the landing page. These are planned; do not assume they exist.
