{
  "openapi": "3.0.3",
  "info": {
    "title": "eunormio API",
    "version": "1.0.0",
    "description": "Erzeugt aus Rechnungsdaten (JSON oder CII-XML) und optionalem PDF eine validierte ZUGFeRD-/Factur-X-Rechnung (PDF/A-3, EN 16931). Jedes Ergebnis durchläuft ein doppeltes Gate (veraPDF + EN-16931-Schematron); nur PASS wird ausgeliefert. Rechnungsdaten werden nur im RAM verarbeitet und nie gespeichert."
  },
  "servers": [
    { "url": "/", "description": "Diese Instanz" }
  ],
  "components": {
    "securitySchemes": {
      "bearerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "API-Token im Format eun_live_… . Ohne (gültigen) Token läuft der Request anonym (Ergebnis mit Wasserzeichen)."
      }
    },
    "schemas": {
      "Report": {
        "type": "object",
        "properties": {
          "timestamp": { "type": "string", "format": "date-time" },
          "service": { "type": "string" },
          "format": { "type": "string", "example": "ZUGFeRD 2 (Factur-X, CII)" },
          "input": { "type": "string", "enum": ["json", "xml-passthrough"] },
          "zugferdProfile": { "type": "string", "example": "EN16931" },
          "pipelineStage": { "type": "string", "enum": ["1", "2", "3a", "3b"] },
          "visual": { "type": "string", "enum": ["vector", "rasterized"] },
          "searchable": { "type": "boolean" },
          "verapdf": { "type": "object", "properties": { "profile": { "type": "string" }, "result": { "type": "string" } } },
          "xml": { "type": "object", "properties": { "profile": { "type": "string" }, "result": { "type": "string" } } },
          "watermark": { "type": "boolean" },
          "auth": { "type": "string", "enum": ["anonymous", "registered"] },
          "tokenWarning": { "type": "string" },
          "quotaNotice": { "type": "string" },
          "sha256": { "type": "string" },
          "durationMs": { "type": "integer" }
        }
      },
      "ConvertSuccess": {
        "type": "object",
        "properties": {
          "pdf": { "type": "string", "format": "byte", "description": "Base64-kodiertes ZUGFeRD-PDF/A-3" },
          "filename": { "type": "string" },
          "ubl": { "type": "string", "description": "XRechnung-UBL-2.1 (nur bei options.includeUbl=true, experimentell)" },
          "report": { "$ref": "#/components/schemas/Report" }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" },
          "stage": { "type": "string", "enum": ["input", "pdfa", "xml", "validation", "quota", "csrf", "internal"] },
          "details": { "type": "array", "items": { "type": "string" } }
        }
      }
    }
  },
  "paths": {
    "/v1/convert": {
      "post": {
        "summary": "Rechnung nach ZUGFeRD/Factur-X konvertieren und validieren",
        "security": [ { "bearerToken": [] }, {} ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "invoice": { "type": "string", "description": "Rechnungsdaten als JSON (Schema siehe /docs). Pflicht, außer bei xml-Passthrough." },
                  "xml": { "type": "string", "format": "binary", "description": "Fertiges CII-XML (CrossIndustryInvoice) — 1:1 eingebettet. In diesem Modus ist pdf Pflicht." },
                  "pdf": { "type": "string", "format": "binary", "description": "Sichtkomponente (≤10 MB, ≤20 Seiten). Ohne Upload: Standardvorlage aus invoice." },
                  "options": { "type": "string", "description": "JSON, optional: {\"profile\":\"EN16931|EXTENDED|XRECHNUNG|BASIC|BASICWL|MINIMUM\", \"includeUbl\":true}" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validiertes ZUGFeRD-PDF/A-3",
            "headers": {
              "X-Eunormio-Auth": { "schema": { "type": "string", "enum": ["anonymous", "registered"] } }
            },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConvertSuccess" } } }
          },
          "422": {
            "description": "Fachlicher Fehler (Eingabe, PDF/A, XML, Validierung)",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          },
          "429": {
            "description": "Rate-Limit oder anonymes Tageslimit erreicht",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "summary": "Health-Check",
        "responses": {
          "200": {
            "description": "Status",
            "content": { "application/json": { "schema": {
              "type": "object",
              "properties": {
                "status": { "type": "string" },
                "service": { "type": "string" },
                "pdftocairo": {},
                "db": { "type": "boolean" }
              }
            } } }
          }
        }
      }
    }
  }
}
