{
  "openapi": "3.1.0",
  "info": {
    "title": "xmoo E-Invoice API",
    "version": "0.1.0",
    "summary": "Validate, read, convert and render European e-invoices (EN 16931, XRechnung, ZUGFeRD / Factur-X).",
    "description": "Validation runs the official artefacts: XML Schema, EN 16931 validation artefacts 1.3.17, KoSIT XRechnung Schematron 2.6.0 and the ZUGFeRD 2.5.2 / Factur-X 1.09.2 rules per profile. Conversions never invent data: if the target format needs something the source does not contain, the API asks for it (`additions_required`), and every change and every loss is listed. A converted document is only returned if it passes the official validation. Invoices are processed in memory and never stored. Provider: Haag Automation (xmoo.app). Same engine as the free tools on https://xmoo.app/tools/e-rechnung-viewer/ and https://xmoo.app/tools/e-rechnung-konverter/. Field names are English. Descriptive texts (changes, losses, notes, error messages) are English by default; `lang=de` returns them in German. Rule texts from the official Schematron are English.",
    "contact": {
      "name": "Haag Automation",
      "email": "julian@haag-automation.com",
      "url": "https://xmoo.app"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.xmoo.app"
    }
  ],
  "paths": {
    "/v1/detect": {
      "post": {
        "summary": "Detect format, syntax and profile",
        "operationId": "detect",
        "requestBody": {
          "$ref": "#/components/requestBodies/Invoice"
        },
        "responses": {
          "200": {
            "description": "Detected",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Detected"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language of descriptive texts (also as `lang` in a JSON body).",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de"
              ],
              "default": "en"
            }
          }
        ]
      }
    },
    "/v1/validate": {
      "post": {
        "summary": "Validate against XML Schema and the official Schematron rules",
        "operationId": "validate",
        "requestBody": {
          "$ref": "#/components/requestBodies/Invoice"
        },
        "responses": {
          "200": {
            "description": "Validation report (also when the invoice is invalid: see `valid`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationResult"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language of descriptive texts (also as `lang` in a JSON body).",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de"
              ],
              "default": "en"
            }
          }
        ]
      }
    },
    "/v1/parse": {
      "post": {
        "summary": "Read the invoice into a JSON model following EN 16931 (business terms BT/BG)",
        "operationId": "parse",
        "requestBody": {
          "$ref": "#/components/requestBodies/Invoice"
        },
        "responses": {
          "200": {
            "description": "Parsed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Parsed"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language of descriptive texts (also as `lang` in a JSON body).",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de"
              ],
              "default": "en"
            }
          }
        ]
      }
    },
    "/v1/convert": {
      "post": {
        "summary": "Convert between XRechnung (UBL/CII) and ZUGFeRD / Factur-X (XML or PDF/A-3)",
        "operationId": "convert",
        "parameters": [
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Target format (required here or as `to` in a JSON body).",
            "schema": {
              "type": "string",
              "enum": [
                "xrechnung-ubl",
                "xrechnung-cii",
                "zugferd",
                "zugferd-pdf"
              ]
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language of descriptive texts (also as `lang` in a JSON body).",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de"
              ],
              "default": "en"
            }
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/Invoice"
        },
        "responses": {
          "200": {
            "description": "Converted and validated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Converted"
                }
              }
            }
          },
          "422": {
            "description": "`additions_required` (with `missing`), `result_not_valid` (with `validation`), `not_convertible` or `already_target_format`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/render": {
      "post": {
        "summary": "Render a human-readable A4 PDF of the invoice",
        "operationId": "render",
        "requestBody": {
          "$ref": "#/components/requestBodies/Invoice"
        },
        "responses": {
          "200": {
            "description": "PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language of descriptive texts (also as `lang` in a JSON body).",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "de"
              ],
              "default": "en"
            }
          }
        ]
      }
    },
    "/v1/formats": {
      "get": {
        "summary": "Supported formats, rule sets and conversion targets",
        "operationId": "formats",
        "responses": {
          "200": {
            "description": "Formats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "requestBodies": {
      "Invoice": {
        "required": true,
        "description": "The invoice as raw XML or PDF (max. 50 MB), or JSON with the file as Base64.",
        "content": {
          "application/xml": {
            "schema": {
              "type": "string"
            }
          },
          "application/pdf": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          },
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JsonInput"
            }
          }
        }
      }
    },
    "responses": {
      "Error": {
        "description": "Error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "JsonInput": {
        "type": "object",
        "required": [
          "document"
        ],
        "properties": {
          "document": {
            "type": "string",
            "description": "The file (XML or PDF) as Base64"
          },
          "to": {
            "type": "string",
            "description": "Only for /v1/convert"
          },
          "additions": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Only for /v1/convert: data the target format needs, keyed by `path` from an `additions_required` answer: buyerReference, seller.electronicAddress, seller.contact.name, seller.contact.telephone, seller.contact.email, seller.address.postCode, seller.address.city, buyer.electronicAddress, buyer.address.postCode, buyer.address.city, payment.iban, payment.bic, payment.accountName. Existing data is never overwritten."
          },
          "lang": {
            "type": "string",
            "enum": [
              "en",
              "de"
            ]
          }
        }
      },
      "Detected": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "xml",
              "pdf"
            ]
          },
          "syntax": {
            "type": "string",
            "enum": [
              "UBL",
              "CII"
            ]
          },
          "documentType": {
            "type": "string",
            "enum": [
              "invoice",
              "credit-note"
            ]
          },
          "specification": {
            "type": [
              "string",
              "null"
            ],
            "description": "BT-24"
          },
          "profile": {
            "type": [
              "string",
              "null"
            ]
          },
          "rulesets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Rule sets /v1/validate applies"
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "rule": {
            "type": "string",
            "example": "BR-CO-15"
          },
          "severity": {
            "type": "string",
            "enum": [
              "error",
              "warning",
              "info"
            ]
          },
          "text": {
            "type": "string"
          },
          "location": {
            "type": "string"
          }
        }
      },
      "Validation": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "No message with severity error"
          },
          "summary": {
            "type": "object",
            "properties": {
              "errors": {
                "type": "integer"
              },
              "warnings": {
                "type": "integer"
              },
              "infos": {
                "type": "integer"
              }
            }
          },
          "reports": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "ruleset": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "messages": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Message"
                  }
                }
              }
            }
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ValidationResult": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Detected"
          },
          {
            "$ref": "#/components/schemas/Validation"
          },
          {
            "type": "object",
            "properties": {
              "totalsCheck": {
                "type": "array",
                "description": "Totals recalculated (BR-CO-10 to -16)",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        ]
      },
      "Parsed": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Detected"
          },
          {
            "type": "object",
            "properties": {
              "invoice": {
                "type": "object",
                "description": "All EN 16931 business terms; values as written in the file"
              },
              "unmapped": {
                "type": "array",
                "description": "Elements EN 16931 does not know (lost in a conversion)",
                "items": {
                  "type": "object"
                }
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "Converted": {
        "type": "object",
        "properties": {
          "target": {
            "type": "string"
          },
          "changes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "losses": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ignoredAdditions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Additions not used because the document does not need them (existing data is never overwritten)"
          },
          "validation": {
            "$ref": "#/components/schemas/Validation"
          },
          "document": {
            "type": "object",
            "properties": {
              "contentType": {
                "type": "string"
              },
              "filename": {
                "type": "string"
              },
              "base64": {
                "type": "string"
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "missing": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "invalid": {
                "type": "object"
              },
              "validation": {
                "$ref": "#/components/schemas/Validation"
              }
            }
          }
        }
      }
    }
  }
}
