Properties
| Name | Type | Description |
|---|---|---|
| invoiceNumber | string | |
| issueDate | string | |
| typeCode | string | BT-3, the document type (UNTDID 1001). XRechnung lists 326 partial invoice, 380 commercial invoice, 381 credit note, 384 corrected invoice, 389 self-billed invoice, 875 partial construction invoice, 8 |
| precedingInvoices | array | BG-3, the invoices this one corrects, credits or settles. BR-DE-26 expects one on a 384. UBL carries any number; CII — and so ZUGFeRD — has room for one, and a second fails the CII schema (422). |
| dueDate | string | BT-9. XRechnung wants this or paymentTerms on a payable invoice. |
| deliveryDate | string | BT-72. Omitting it and `invoicePeriod` draws an advisory from the rule set. |
| deliverTo | object | |
| invoicePeriod | object | BG-14, the period a monthly or yearly invoice covers — instead of `deliveryDate`, or beside it. |
| currency | string | |
| buyerReference | string | BT-10. For public-sector invoices this is the Leitweg-ID. Mandatory in every XRechnung (BR-DE-15), optional with `profile=en16931`. |
| orderReference | string | BT-13, the buyer's purchase order number. |
| contractReference | string | BT-12. |
| projectReference | string | BT-11. |
| despatchAdviceReference | string | BT-16, the delivery note (Lieferschein) the goods came with. |
| attachments | array | BG-24, the documents that support the invoice — a timesheet, a delivery note, photos of the work — inside it or by link. Their files may hold 3 MB together (4 MB as base64), so the invoice that carrie |
| note | string | BT-22. |
| seller | object | |
| buyer | object | |
| payment | object | |
| paymentTerms | string | |
| allowances | array | BG-20, allowances on the whole document. |
| charges | array | BG-21, charges on the whole document — freight, packaging. |
| prepaidAmount | number | BT-113, already paid — the advances a final invoice (877) settles. The amount due (BT-115) is the gross total less this. Two decimals. |
| lines | array |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/api-evangelist/normapi-com/main/json-schema/normapi-com-invoice-request-schema.json",
"title": "InvoiceRequest",
"x-generated": "2026-10-26",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/normapi-com-generation-api-openapi.yml#/components/schemas/InvoiceRequest",
"type": "object",
"required": [
"invoiceNumber",
"issueDate",
"currency",
"seller",
"buyer",
"payment",
"lines"
],
"properties": {
"invoiceNumber": {
"type": "string"
},
"issueDate": {
"type": "string",
"format": "date"
},
"typeCode": {
"type": "string",
"pattern": "^[0-9]{3}$",
"default": "380",
"description": "BT-3, the document type (UNTDID 1001). XRechnung lists 326 partial\ninvoice, 380 commercial invoice, 381 credit note, 384 corrected\ninvoice, 389 self-billed invoice, 875 partial construction invoice,\n876 partial final construction invoice and 877 final construction\ninvoice; any other code draws the BR-DE-17 warning. A 381 is\ngenerated as a UBL CreditNote, where the due date moves into the\npayment means.\n"
},
"precedingInvoices": {
"type": "array",
"description": "BG-3, the invoices this one corrects, credits or settles. BR-DE-26\nexpects one on a 384. UBL carries any number; CII — and so\nZUGFeRD — has room for one, and a second fails the CII schema\n(422).\n",
"items": {
"$ref": "#/$defs/PrecedingInvoice"
}
},
"dueDate": {
"type": "string",
"format": "date",
"description": "BT-9. XRechnung wants this or paymentTerms on a payable invoice."
},
"deliveryDate": {
"type": "string",
"format": "date",
"description": "BT-72. Omitting it and `invoicePeriod` draws an advisory from the\nrule set.\n"
},
"deliverTo": {
"$ref": "#/$defs/DeliverTo"
},
"invoicePeriod": {
"$ref": "#/$defs/Period",
"description": "BG-14, the period a monthly or yearly invoice covers — instead of\n`deliveryDate`, or beside it.\n"
},
"currency": {
"type": "string"
},
"buyerReference": {
"type": "string",
"maxLength": 200,
"description": "BT-10. For public-sector invoices this is the Leitweg-ID. Mandatory\nin every XRechnung (BR-DE-15), optional with `profile=en16931`.\n"
},
"orderReference": {
"type": "string",
"maxLength": 100,
"description": "BT-13, the buyer's purchase order number."
},
"contractReference": {
"type": "string",
"maxLength": 100,
"description": "BT-12."
},
"projectReference": {
"type": "string",
"maxLength": 100,
"description": "BT-11."
},
"despatchAdviceReference": {
"type": "string",
"maxLength": 100,
"description": "BT-16, the delivery note (Lieferschein) the goods came with."
},
"attachments": {
"type": "array",
"maxItems": 20,
"description": "BG-24, the documents that support the invoice — a timesheet, a\ndelivery note, photos of the work — inside it or by link. Their\nfiles may hold 3 MB together (4 MB as base64), so the invoice that\ncarries them stays within the 5 MB the validator accepts; a JSON\nbody over 6 MB is refused with 413. In CII, and so in ZUGFeRD, more\nthan one file or more than one description draws the warnings\nCII-SR-476 and CII-SR-475, a known defect of those CEN rules; the\ninvoice is accepted.\n",
"items": {
"$ref": "#/$defs/Attachment"
}
},
"note": {
"type": "string",
"maxLength": 1000,
"description": "BT-22."
},
"seller": {
"$ref": "#/$defs/Party"
},
"buyer": {
"$ref": "#/$defs/Party"
},
"payment": {
"$ref": "#/$defs/Payment"
},
"paymentTerms": {
"type": "string"
},
"allowances": {
"type": "array",
"description": "BG-20, allowances on the whole document.",
"items": {
"$ref": "#/$defs/AllowanceCharge"
}
},
"charges": {
"type": "array",
"description": "BG-21, charges on the whole document — freight, packaging.",
"items": {
"$ref": "#/$defs/AllowanceCharge"
}
},
"prepaidAmount": {
"type": "number",
"description": "BT-113, already paid — the advances a final invoice (877) settles.\nThe amount due (BT-115) is the gross total less this. Two decimals.\n"
},
"lines": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/Line"
}
}
},
"$defs": {
"Address": {
"type": "object",
"description": "A postal address: the seller's (BG-5), the buyer's (BG-8) or the\ndelivery's (BG-15). City and postcode are mandatory in XRechnung for\nall three (BR-DE-3/4, BR-DE-8/9, BR-DE-10/11).\n",
"required": [
"city",
"postcode",
"country"
],
"properties": {
"street": {
"type": "string",
"description": "BT-35 / BT-50 / BT-75."
},
"city": {
"type": "string",
"description": "BT-37 / BT-52 / BT-77."
},
"postcode": {
"type": "string",
"description": "BT-38 / BT-53 / BT-78."
},
"country": {
"type": "string",
"description": "BT-40 / BT-55 / BT-80, ISO 3166-1 alpha-2."
}
}
},
"AllowanceCharge": {
"type": "object",
"description": "A document-level allowance (BG-20, BT-92 to BT-98) or charge (BG-21,\nBT-99 to BT-105) — which one is decided by the list it stands in.\nGive `amount` or `percent`, exactly one. With `percent` the amount is\ncomputed: base × percent / 100, rounded half-up to the cent. It moves\nthe taxable amount of its own VAT category and rate.\n",
"required": [
"vatCategory"
],
"properties": {
"amount": {
"type": "number",
"description": "BT-92 / BT-99, two decimals."
},
"percent": {
"type": "number",
"description": "BT-94 / BT-101."
},
"baseAmount": {
"type": "number",
"description": "BT-93 / BT-100, what the percentage is taken of. Without it: the\nline nets of the lines in the same VAT category and rate — and if\nthere are none, the request is a 400. Only with `percent`: beside\na plain `amount` the rule set refuses it (PEPPOL-EN16931-R042).\n"
},
"reason": {
"type": "string",
"description": "BT-97 / BT-104. This or `reasonCode` is required (BR-33, BR-38)."
},
"reasonCode": {
"type": "string",
"description": "BT-98 (UNTDID 5189, e.g. 95 discount) / BT-105 (UNTDID 7161, e.g. FC freight)."
},
"vatCategory": {
"type": "string",
"description": "BT-95 / BT-102."
},
"vatRate": {
"type": "number",
"description": "BT-96 / BT-103."
},
"vatExemptionReason": {
"type": "string",
"description": "BT-120 for the VAT group this falls into, as on a line."
}
}
},
"Attachment": {
"type": "object",
"description": "One supporting document (BG-24): a file inside the invoice\n(`content` with `filename` and `mimeCode`), a link (`url`), or a\nreference alone. Which types are permitted is the rule set's verdict\n(BR-CL-24: PDF, PNG, JPEG, CSV, XLSX, ODS), as is a filename used\ntwice (BR-DE-22) — both come back as a 422. A file that is not what\nits `mimeCode` says, as far as its first bytes tell, is a 400. In a\nZUGFeRD PDF the files travel in the embedded XML, and the invoice page\nlists them by name.\n",
"properties": {
"id": {
"type": "string",
"maxLength": 200,
"description": "BT-122, the document's own number or name; the filename when absent (BR-52)."
},
"description": {
"type": "string",
"maxLength": 500,
"description": "BT-123."
},
"filename": {
"type": "string",
"maxLength": 200,
"description": "BT-125-2, unique within the invoice (BR-DE-22)."
},
"mimeCode": {
"type": "string",
"maxLength": 100,
"description": "BT-125-1, one of the six types BR-CL-24 permits."
},
"content": {
"type": "string",
"format": "byte",
"description": "BT-125, the file as base64. Comes with `filename` and `mimeCode`."
},
"url": {
"type": "string",
"maxLength": 2000,
"pattern": "^https?://\\S+$",
"description": "BT-124, where the buyer can fetch the document."
}
}
},
"Card": {
"type": "object",
"description": "BG-18, with payment means 48, 54 or 55.",
"required": [
"number"
],
"properties": {
"number": {
"type": "string",
"description": "BT-87, the masked card number. More than 10 digits is a 400: at\nmost the first 6 and the last 4 may appear on an invoice. BR-51\ncounts characters, not digits — over 10 is rejected in CII and\nwarned about in UBL — so send the digits without mask characters.\n"
},
"holder": {
"type": "string",
"description": "BT-88, the cardholder."
},
"network": {
"type": "string",
"description": "The card network; UBL requires one and gets NA when absent."
}
}
},
"DeliverTo": {
"type": "object",
"description": "BG-13 apart from its date (`deliveryDate`, BT-72): where the supply\nwent, when not simply to the buyer. Every part is optional, and an\nempty one is not written. An intra-community supply (VAT category K)\nis refused without the country the goods went to (BR-IC-12), so it\nneeds at least `address`.\n",
"properties": {
"name": {
"type": "string",
"description": "BT-70, who received the goods — a branch, a warehouse, a site."
},
"locationId": {
"type": "string",
"description": "BT-71, an identifier of the place, e.g. its GLN."
},
"locationIdScheme": {
"type": "string",
"pattern": "^[0-9]{4}$",
"description": "BT-71-1, the ISO 6523 ICD of `locationId`: 0088 for a GLN. Without\none the identifier is written as the seller's own.\n"
},
"address": {
"$ref": "#/$defs/Address"
}
}
},
"DirectDebit": {
"type": "object",
"description": "BG-19, with payment means 59. Optional in the request, all three\nrequired by the rule set: the creditor identifier and the debited\naccount by BR-DE-30 and BR-DE-31, the mandate reference by\nPEPPOL-EN16931-R061. Leave out the payee IBAN — the money is\ncollected, not transferred (BR-DE-25-b).\n",
"properties": {
"mandateReference": {
"type": "string",
"description": "BT-89."
},
"creditorId": {
"type": "string",
"description": "BT-90, the SEPA creditor identifier (Gläubiger-ID)."
},
"debitedAccount": {
"type": "string",
"description": "BT-91, the buyer's IBAN the amount is collected from."
}
}
},
"Line": {
"type": "object",
"required": [
"name",
"quantity",
"unit",
"unitPrice",
"vatCategory"
],
"properties": {
"id": {
"type": "string",
"description": "BT-126; assigned 1..n when absent."
},
"name": {
"type": "string",
"description": "BT-153."
},
"description": {
"type": "string",
"description": "BT-154."
},
"quantity": {
"type": "number"
},
"unit": {
"type": "string"
},
"unitPrice": {
"type": "number",
"description": "BT-146, the net price — per `baseQuantity` units when one is given."
},
"vatCategory": {
"type": "string"
},
"vatRate": {
"type": "number",
"description": "BT-152, percent; required for category S."
},
"vatExemptionReason": {
"type": "string",
"description": "BT-120; the rule set wants it for the exempt-family categories."
},
"allowances": {
"type": "array",
"description": "BG-27; the line net (BT-131) is quantity × unit price ÷ base quantity, less these.",
"items": {
"$ref": "#/$defs/LineAllowanceCharge"
}
},
"charges": {
"type": "array",
"description": "BG-28; the line net (BT-131) is quantity × unit price ÷ base quantity, plus these.",
"items": {
"$ref": "#/$defs/LineAllowanceCharge"
}
},
"period": {
"$ref": "#/$defs/Period",
"description": "BG-26, the period this line covers — a month of a subscription."
},
"orderLineReference": {
"type": "string",
"maxLength": 50,
"description": "BT-132, the line of the buyer's purchase order this one bills."
},
"note": {
"type": "string",
"maxLength": 1000,
"description": "BT-127, free text on this line alone."
},
"sellerItemId": {
"type": "string",
"maxLength": 100,
"description": "BT-155, the seller's article number."
},
"buyerItemId": {
"type": "string",
"maxLength": 100,
"description": "BT-156, the buyer's own number for the article."
},
"standardItemId": {
"type": "string",
"maxLength": 100,
"description": "BT-157, an identifier under a registered scheme — the GTIN (EAN) on the packaging."
},
"standardItemIdScheme": {
"type": "string",
"pattern": "^[0-9]{4}$",
"description": "BT-157-1, the ISO 6523 ICD of `standardItemId`; `0160` (GTIN) when absent."
},
"listPrice": {
"type": "number",
"description": "BT-148, the price before the item's price discount, at least\n`unitPrice`. The discount (BT-147) is `listPrice − unitPrice`, so it\nis never sent separately.\n"
},
"baseQuantity": {
"type": "number",
"exclusiveMinimum": 0,
"description": "BT-149, how many units `unitPrice` and `listPrice` are for — 100 for\nscrews priced per hundred; 1 when absent. The line net is then\nquantity × unit price ÷ base quantity.\n"
}
}
},
"LineAllowanceCharge": {
"type": "object",
"description": "A line allowance (BG-27, BT-136 to BT-140) or charge (BG-28, BT-141\nto BT-145). Give `amount` or `percent`, exactly one. It carries no VAT\nof its own: it changes the line net (BT-131), which stays in the\nline's VAT category.\n",
"properties": {
"amount": {
"type": "number",
"description": "BT-136 / BT-141, two decimals."
},
"percent": {
"type": "number",
"description": "BT-138 / BT-143."
},
"baseAmount": {
"type": "number",
"description": "BT-137 / BT-142. Without it: the line's quantity × unit price,\nrounded to the cent. Only with `percent` (PEPPOL-EN16931-R042).\n"
},
"reason": {
"type": "string",
"description": "BT-139 / BT-144. This or `reasonCode` is required (BR-42, BR-44)."
},
"reasonCode": {
"type": "string",
"description": "BT-140 (UNTDID 5189) / BT-145 (UNTDID 7161)."
}
}
},
"Party": {
"type": "object",
"required": [
"name",
"address"
],
"properties": {
"name": {
"type": "string",
"description": "BT-27 / BT-44, the legal name."
},
"identifier": {
"type": "string",
"description": "BT-29 / BT-46. A seller without a VAT id repeats its tax number here:\nBT-32 alone satisfies BR-DE-16 but not BR-CO-26.\n"
},
"vatId": {
"type": "string",
"description": "BT-31 / BT-48."
},
"taxNumber": {
"type": "string",
"description": "BT-32, the German Steuernummer."
},
"electronicAddress": {
"type": "string",
"description": "BT-34 / BT-49, an email address unless the scheme says otherwise.\nXRechnung requires it on both sides (PEPPOL-EN16931-R020 and\nR010); EN 16931 does not.\n"
},
"electronicAddressScheme": {
"type": "string"
},
"address": {
"$ref": "#/$defs/Address"
},
"contact": {
"type": "object",
"description": "BG-6. XRechnung requires it on the seller with all three parts\n(BR-DE-2, BR-DE-5 to 7), and a missing contact is the most common\nmapping error there. With `profile=en16931` it is optional, and\nany part may stand alone.\n",
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"description": "BT-41."
},
"phone": {
"type": "string",
"maxLength": 50,
"description": "BT-42."
},
"email": {
"type": "string",
"maxLength": 254,
"description": "BT-43."
}
}
},
"tradingName": {
"type": "string",
"maxLength": 200,
"description": "BT-28 / BT-45, the name the party trades under beside its legal\none. On the ZUGFeRD page it heads the seller block, and the legal\nname opens the address line.\n"
},
"registrationId": {
"type": "string",
"maxLength": 100,
"description": "BT-30 / BT-47, the register entry. Like `identifier` and `vatId`\nit identifies a seller for BR-CO-26.\n"
},
"registrationIdScheme": {
"type": "string",
"pattern": "^[0-9]{4}$",
"description": "BT-30-1 / BT-47-1, the ISO 6523 ICD of `registrationId`. German\nregister numbers have none; a French SIREN is 0002.\n"
},
"legalInformation": {
"type": "string",
"maxLength": 1000,
"description": "BT-33, the seller's only — on the buyer it is a 400. What company\nlaw wants on business letters beyond the name and the register\nnumber: the seat, the register court, the managing directors\n(§ 35a GmbHG, § 80 AktG, § 37a HGB). The ZUGFeRD page prints it\nwith the register number.\n"
}
}
},
"Payment": {
"type": "object",
"description": "BG-16, and the group its code calls for: the payee account (BG-17)\nfor a transfer, `card` (BG-18) for a card payment, `directDebit`\n(BG-19) for a SEPA direct debit. Which group may stand beside which\ncode is the rule set's verdict (BR-DE-23 to BR-DE-25), returned as\nfindings — a payee IBAN beside a direct debit is a 422, not a 400.\n",
"required": [
"meansCode"
],
"properties": {
"meansCode": {
"type": "string",
"pattern": "^([0-9]{1,3}|ZZZ)$",
"description": "BT-81, UNTDID 4461: 58 SEPA credit transfer, 30 credit transfer,\n59 SEPA direct debit, 48/54/55 card, 10 cash, ZZZ mutually defined.\n"
},
"meansText": {
"type": "string",
"description": "BT-82, the payment means in words."
},
"iban": {
"type": "string",
"description": "BT-84, the payee account."
},
"accountName": {
"type": "string",
"description": "BT-85, the payee account holder."
},
"bic": {
"type": "string",
"pattern": "^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$",
"description": "BT-86, the payee's bank."
},
"reference": {
"type": "string",
"description": "BT-83, what the payer should quote."
},
"card": {
"$ref": "#/$defs/Card"
},
"directDebit": {
"$ref": "#/$defs/DirectDebit"
}
}
},
"Period": {
"type": "object",
"description": "A period, the invoice's (BG-14) or a line's (BG-26). Either end may\nstand alone; the rule set wants one of them (BR-CO-19, BR-CO-20) and\nthe end not before the start (BR-29, BR-30). An empty period is not\nwritten.\n",
"properties": {
"startDate": {
"type": "string",
"format": "date",
"description": "BT-73 / BT-134."
},
"endDate": {
"type": "string",
"format": "date",
"description": "BT-74 / BT-135."
}
}
},
"PrecedingInvoice": {
"type": "object",
"required": [
"number"
],
"properties": {
"number": {
"type": "string",
"description": "BT-25."
},
"issueDate": {
"type": "string",
"format": "date",
"description": "BT-26, needed when the number alone is not unique."
}
}
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/normapi-com-invoice-request"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.