{
  "openapi": "3.1.0",
  "info": {
    "title": "Invoice-Converter External API V1",
    "version": "1.5.0",
    "description": "Headless partner API for converting PDF invoices to European e-invoicing formats. Access is available to Enterprise partners and prepaid API-credit testers.",
    "x-last-updated": "2026-05-08"
  },
  "servers": [
    {
      "url": "https://invoice-converter.com",
      "description": "API host for approved partners and prepaid API-credit testers (paths in this document include /api/v1)"
    }
  ],
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "paths": {
    "/api/v1/invoices:convert": {
      "post": {
        "summary": "Convert a PDF invoice asynchronously",
        "operationId": "convertInvoiceV1",
        "tags": [
          "Invoices"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/XCorrelationIdHeader"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ConvertInvoiceRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted: conversion task started",
            "headers": {
              "X-Correlation-ID": {
                "$ref": "#/components/headers/XCorrelationId"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConvertAcceptedResponse"
                },
                "example": {
                  "task_id": "550e8400-e29b-41d4-a716-446655440000",
                  "status": "pending",
                  "message": "PDF accepted. Conversion started.",
                  "filename": "invoice.pdf",
                  "file_size": 245832,
                  "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedMediaType"
          },
          "422": {
            "$ref": "#/components/responses/UploadFailed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/ProxyErrorBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/ProxyErrorGatewayTimeout"
          }
        }
      }
    },
    "/api/v1/tasks/{task_id}": {
      "get": {
        "summary": "Poll task status",
        "operationId": "getTaskStatusV1",
        "tags": [
          "Tasks"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskIdPath"
          },
          {
            "$ref": "#/components/parameters/XCorrelationIdHeader"
          }
        ],
        "responses": {
          "200": {
            "description": "Task status retrieved",
            "headers": {
              "X-Correlation-ID": {
                "$ref": "#/components/headers/XCorrelationId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskStatusResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/TaskStatusFailed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/ProxyErrorBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/ProxyErrorGatewayTimeout"
          }
        }
      }
    },
    "/api/v1/tasks/{task_id}/result": {
      "get": {
        "summary": "Download conversion result",
        "operationId": "getTaskResultV1",
        "tags": [
          "Tasks"
        ],
        "description": "Returns the generated file directly. Content-Type is application/xml for XML outputs or application/pdf for PDF outputs. Successful downloads may include additive artifact-state headers for compliant versus warning-only diagnostics. Returns 422 VALIDATION_FAILED when blocking issues remain.",
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskIdPath"
          },
          {
            "$ref": "#/components/parameters/XCorrelationIdHeader"
          },
          {
            "$ref": "#/components/parameters/DownloadQuery"
          }
        ],
        "responses": {
          "200": {
            "description": "Generated file (XML or PDF)",
            "headers": {
              "Content-Disposition": {
                "description": "Attachment filename, for example: attachment; filename=invoice.xml",
                "schema": {
                  "type": "string"
                }
              },
              "X-Artifact-State": {
                "description": "Additive artifact readiness diagnostic for successful downloads (`compliant` or `warning_only`).",
                "schema": {
                  "type": "string",
                  "enum": [
                    "compliant",
                    "warning_only"
                  ]
                }
              },
              "X-Correlation-ID": {
                "$ref": "#/components/headers/XCorrelationId"
              },
              "X-Material-Edits": {
                "description": "Whether the successful artifact reflects material edits relative to the immutable extracted/source baseline.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "X-Pdf-Xml-Parity": {
                "description": "Hybrid parity diagnostic for successful downloads (`aligned`, `diverged`, or `not_applicable`).",
                "schema": {
                  "type": "string",
                  "enum": [
                    "aligned",
                    "diverged",
                    "not_applicable"
                  ]
                }
              },
              "X-Validation-Proof-Id": {
                "description": "Backend validation proof identifier for the exact returned bytes or a persisted derivation proof.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Validation-State": {
                "description": "Validation diagnostic for successful downloads (`passed`, `failed_overridable`, or `not_validated`).",
                "schema": {
                  "type": "string",
                  "enum": [
                    "passed",
                    "failed_overridable",
                    "not_validated"
                  ]
                }
              },
              "X-Warning-Reason-Codes": {
                "description": "Comma-separated additive warning reason codes, for example `material_edits,pdf_xml_diverged` or `validator_unavailable`.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "202": {
            "$ref": "#/components/responses/TaskNotReady"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/TaskResultFailed"
          },
          "422": {
            "$ref": "#/components/responses/ValidationFailed"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "$ref": "#/components/responses/ProxyErrorBadGateway"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/ProxyErrorGatewayTimeout"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "HTTPBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key"
      }
    },
    "parameters": {
      "XCorrelationIdHeader": {
        "name": "X-Correlation-ID",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Optional correlation ID for request tracing. Generated automatically when omitted."
      },
      "IdempotencyKeyHeader": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200,
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$"
        },
        "description": "Required on write endpoints for safe retries. Reuse the same key with the same payload."
      },
      "TaskIdPath": {
        "name": "task_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Task UUID returned by the convert endpoint."
      },
      "DownloadQuery": {
        "name": "download",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "xml",
            "pdf"
          ],
          "default": "xml"
        },
        "description": "Requested output format for result download."
      }
    },
    "headers": {
      "XCorrelationId": {
        "description": "Correlation ID for end-to-end request tracing.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying after a 429.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "XRateLimitLimitMinute": {
        "description": "Effective minute quota for this endpoint/key.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "XRateLimitLimitHour": {
        "description": "Effective hour quota for this endpoint/key.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "IdempotencyReplayed": {
        "description": "Set to true when the response is a replay for a previous identical idempotent request.",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Authentication failed",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          },
          "WWW-Authenticate": {
            "schema": {
              "type": "string",
              "example": "Bearer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Prepaid API credits are required for this conversion request",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "INSUFFICIENT_API_CREDITS",
              "message": "Prepaid API credits are required for External API conversions",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
              "details": {
                "type": "context",
                "remaining": 0,
                "minimum_purchase": 10
              }
            }
          }
        }
      },
      "Conflict": {
        "description": "Idempotency conflict or request already in progress",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "Request payload exceeds limits",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "UnsupportedMediaType": {
        "description": "Upload must be sent as multipart/form-data with a file field named file",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "INVALID_UPLOAD",
              "message": "Unable to parse multipart request body. Send multipart/form-data with a file field named 'file'.",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
              "details": {
                "expected_content_type": "multipart/form-data",
                "required_file_field": "file",
                "received_content_type": "application/json",
                "docs_url": "https://invoice-converter.com/en/developer-api"
              }
            }
          }
        }
      },
      "UploadFailed": {
        "description": "Upload or request option validation failed",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "UPLOAD_FAILED",
              "message": "Invalid format. Allowed values: CII, EN16931, UBL, XRECHNUNG, ZUGFERD",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          },
          "X-RateLimit-Limit-Minute": {
            "$ref": "#/components/headers/XRateLimitLimitMinute"
          },
          "X-RateLimit-Limit-Hour": {
            "$ref": "#/components/headers/XRateLimitLimitHour"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "RATE_LIMITED",
              "message": "Rate limit exceeded",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
              "details": {
                "type": "rate_limit",
                "minute_count": 31,
                "hour_count": 501,
                "limit_minute": 30,
                "limit_hour": 500
              }
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Dependency unavailable (auth or rate-limit service)",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ProxyErrorBadGateway": {
        "description": "Proxy or upstream connection failure",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "PROXY_ERROR",
              "message": "Proxy request failed",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
            }
          }
        }
      },
      "ProxyErrorGatewayTimeout": {
        "description": "Proxy timeout while waiting for upstream",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "PROXY_ERROR",
              "message": "Upstream timeout",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
            }
          }
        }
      },
      "TaskNotReady": {
        "description": "Task exists but conversion is still in progress",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "TASK_NOT_READY",
              "message": "Conversion in progress, result not ready yet",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
            }
          }
        }
      },
      "TaskStatusFailed": {
        "description": "Task not found or status could not be retrieved",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "TaskResultFailed": {
        "description": "Task not found or result could not be retrieved",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ValidationFailed": {
        "description": "Blocking validation errors prevent file delivery",
        "headers": {
          "X-Correlation-ID": {
            "$ref": "#/components/headers/XCorrelationId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "code": "VALIDATION_FAILED",
              "message": "Validation failed",
              "correlation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
              "details": {
                "type": "validation",
                "items": [
                  {
                    "field": "BuyerReference",
                    "rule_id": "BR-DE-15",
                    "severity": "error",
                    "source": "task-result-download",
                    "suggestion": "Provide Leitweg-ID / BuyerReference."
                  }
                ]
              }
            }
          }
        }
      }
    },
    "schemas": {
      "ConvertInvoiceRequest": {
        "type": "object",
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "PDF invoice file to convert."
          },
          "format": {
            "type": "string",
            "enum": [
              "XRECHNUNG",
              "ZUGFERD",
              "EN16931",
              "UBL",
              "CII"
            ],
            "default": "XRECHNUNG",
            "description": "Target output format. XRECHNUNG, ZUGFERD, EN16931, UBL, and CII are supported. ZUGFERD maps to an EN16931 ZUGFeRD/Factur-X hybrid PDF by default."
          }
        },
        "additionalProperties": false
      },
      "ConvertAcceptedResponse": {
        "type": "object",
        "required": [
          "task_id",
          "status",
          "correlation_id"
        ],
        "properties": {
          "task_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing"
            ]
          },
          "message": {
            "type": "string"
          },
          "filename": {
            "type": [
              "string",
              "null"
            ]
          },
          "file_size": {
            "type": "integer",
            "minimum": 0
          },
          "correlation_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "additionalProperties": false
      },
      "TaskStatusResponse": {
        "type": "object",
        "required": [
          "task_id",
          "status",
          "correlation_id"
        ],
        "properties": {
          "task_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "progress": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100
          },
          "filename": {
            "type": [
              "string",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "correlation_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "additionalProperties": false
      },
      "ValidationDetail": {
        "type": "object",
        "properties": {
          "field": {
            "type": [
              "string",
              "null"
            ]
          },
          "rule_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "severity": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "suggestion": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true
      },
      "ErrorDetails": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "validation",
              "rate_limit",
              "idempotency_conflict",
              "idempotency_in_progress",
              "profile_mismatch",
              "context",
              "message"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationDetail"
            }
          },
          "minute_count": {
            "type": "integer"
          },
          "hour_count": {
            "type": "integer"
          },
          "limit_minute": {
            "type": "integer"
          },
          "limit_hour": {
            "type": "integer"
          },
          "reason": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "profile_conflict": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "code",
          "message",
          "correlation_id"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "correlation_id": {
            "type": "string",
            "format": "uuid"
          },
          "details": {
            "$ref": "#/components/schemas/ErrorDetails"
          }
        },
        "additionalProperties": false
      }
    }
  }
}
