{
  "openapi": "3.1.0",
  "info": {
    "title": "CodeB eForms Server API",
    "version": "1.0.0",
    "description": "REST API of the CodeB eForms Server by Aloaha Limited (Malta). List forms, read their fields and field types, validate data, fill and submit forms, create ZUGFeRD / Factur-X / XRechnung e-invoices, send prefilled form links and receive every submission by webhook (Standard Webhooks).\n\n**Authentication:** every call except `/`, `/health`, `/openapi` and `/field-types` needs `Authorization: Bearer <token>` with an access token (or ID token) of one of the OIDC sign-in servers configured on this form server (see `GET /` → `issuers`). JWTs must be RS256 signed, unexpired and issued for this server's client ID (or a client ID the administrator allowed). Opaque tokens are checked by token introspection; with more than one sign-in server send the header `X-OIDC-Issuer: <host>`.\n\n**Roles** come from the token's `role` claim: `admin` and `user` see the forms of their group (the sign-in server's host name), `guest` only released forms. Submitting needs `user` or `admin` unless the server allows guests.\n\n**Submissions** go through the same processing as the web form: the PDF is sealed (and signed if configured), e-invoices are embedded, and e-mails go to the business owner and to e-mail addresses found in the data.",
    "contact": {
      "name": "Aloaha Limited",
      "email": "info@aloaha.com",
      "url": "https://www.form-provider.com/"
    }
  },
  "servers": [
    {
      "url": "https://www.form-provider.com/api/v1"
    }
  ],
  "tags": [
    {
      "name": "Service"
    },
    {
      "name": "Forms"
    },
    {
      "name": "Submissions"
    },
    {
      "name": "E-invoices"
    },
    {
      "name": "Webhooks",
      "description": "Get every submission of a form pushed to your system, signed as Standard Webhooks."
    },
    {
      "name": "Prefilled links"
    },
    {
      "name": "Usage"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT (RS256) or opaque OAuth 2.0 access token",
        "description": "Access token of a configured OIDC server (e.g. phone.codeb.io)."
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details.",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            }
          }
        },
        "required": [
          "title",
          "status",
          "detail"
        ]
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "description": "submitName of the field"
          },
          "code": {
            "type": "string",
            "enum": [
              "required",
              "invalid_value",
              "invalid_format",
              "too_long",
              "invalid_type",
              "unknown_field"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Links": {
        "type": "object",
        "properties": {
          "responsive": {
            "type": "string",
            "format": "uri"
          },
          "static": {
            "type": "string",
            "format": "uri"
          },
          "pdf": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Form": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "group": {
            "type": "string"
          },
          "released": {
            "type": "boolean"
          },
          "modified": {
            "type": "string",
            "format": "date-time"
          },
          "releasedAt": {
            "type": "string",
            "format": "date-time"
          },
          "links": {
            "$ref": "#/components/schemas/Links"
          }
        },
        "required": [
          "id",
          "title",
          "group",
          "released"
        ]
      },
      "FormDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Form"
          },
          {
            "type": "object",
            "properties": {
              "internalId": {
                "type": "string"
              },
              "pageCount": {
                "type": "integer"
              },
              "inputFieldCount": {
                "type": "integer"
              },
              "settings": {
                "type": "object",
                "properties": {
                  "requiresSignIn": {
                    "type": "boolean"
                  },
                  "requiresUpload": {
                    "type": "boolean"
                  },
                  "imagesOnly": {
                    "type": "boolean"
                  },
                  "noSubmitButton": {
                    "type": "boolean"
                  },
                  "noEmail": {
                    "type": "boolean"
                  },
                  "mailFieldsOnly": {
                    "type": "boolean"
                  }
                }
              },
              "notification": {
                "type": "object",
                "description": "Only for role user/admin.",
                "properties": {
                  "designerEmail": {
                    "type": "string"
                  },
                  "businessOwnerEmail": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ]
      },
      "FieldType": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "editorName": {
            "type": "string"
          },
          "editorCode": {
            "type": "string"
          },
          "input": {
            "type": "boolean"
          },
          "description": {
            "type": "string"
          }
        }
      },
      "Field": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Field number in the form"
          },
          "name": {
            "type": "string",
            "description": "Field name (PDF field / XML element)"
          },
          "type": {
            "type": "string",
            "enum": [
              "textfield",
              "dropdown",
              "checkbox",
              "radio",
              "text",
              "image",
              "line",
              "button"
            ]
          },
          "input": {
            "type": "boolean",
            "description": "true = a value can be submitted"
          },
          "submitName": {
            "type": "string",
            "description": "Key to use in values (radio buttons: the group ID)"
          },
          "label": {
            "type": "string"
          },
          "groupId": {
            "type": "string"
          },
          "pages": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "position": {
            "type": "object",
            "description": "Points (1/72 inch). x from the left edge, y = top edge measured from the bottom of the page (as in the editor).",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              },
              "width": {
                "type": "number"
              },
              "height": {
                "type": "number"
              }
            }
          },
          "required": {
            "type": "boolean"
          },
          "multiline": {
            "type": "boolean"
          },
          "maxLength": {
            "type": "integer"
          },
          "comb": {
            "type": "boolean"
          },
          "validation": {
            "type": "object",
            "properties": {
              "rule": {
                "type": "string"
              },
              "pattern": {
                "type": "string"
              }
            }
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "checked": {
            "type": "boolean"
          },
          "value": {
            "type": "string",
            "description": "Radio button: the value that selects it"
          },
          "defaultValue": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "input",
          "pages",
          "position"
        ]
      },
      "ValidationRule": {
        "type": "object",
        "properties": {
          "rule": {
            "type": "string"
          },
          "pattern": {
            "type": "string"
          }
        }
      },
      "Me": {
        "type": "object",
        "properties": {
          "user": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "user",
              "guest"
            ]
          },
          "group": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "clientId": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SubmitRequest": {
        "type": "object",
        "properties": {
          "values": {
            "type": "object",
            "additionalProperties": {
              "type": [
                "string",
                "number",
                "boolean"
              ]
            },
            "description": "submitName → value. Check boxes: true/false. Drop-downs and radio groups: one of the options."
          },
          "ignoreUnknownFields": {
            "type": "boolean",
            "default": false,
            "description": "Skip values whose name the form does not have (default: reject them)."
          },
          "useIdentity": {
            "type": "boolean",
            "default": false,
            "description": "Hand the caller's verified identity to the form (always done for forms that require sign-in); fills fields such as FirstName, Surname, Email."
          },
          "returnPdf": {
            "type": "string",
            "enum": [
              "base64",
              "none",
              "binary"
            ],
            "default": "base64",
            "description": "How the resulting PDF is returned. binary (or Accept: application/pdf) returns the PDF itself."
          }
        },
        "example": {
          "values": {
            "Surname": "Muster",
            "FirstName": "Erika",
            "Email": "erika@example.com",
            "Consent": true
          }
        }
      },
      "SubmissionResult": {
        "type": "object",
        "properties": {
          "submissionId": {
            "type": "string"
          },
          "formId": {
            "type": "string"
          },
          "action": {
            "type": "string",
            "enum": [
              "submit",
              "fill"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "submitted",
              "filled"
            ]
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "pdf": {
            "type": "object",
            "properties": {
              "fileName": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "size": {
                "type": "integer"
              },
              "sha256": {
                "type": "string"
              },
              "eInvoice": {
                "type": "boolean",
                "description": "true when ZUGFeRD / Factur-X / XRechnung XML is embedded"
              },
              "data": {
                "type": "string",
                "contentEncoding": "base64"
              }
            }
          },
          "totals": {
            "type": "object",
            "description": "Only for /einvoices.",
            "properties": {
              "lineTotal": {
                "type": "number"
              },
              "taxTotal": {
                "type": "number"
              },
              "grandTotal": {
                "type": "number"
              },
              "currency": {
                "type": "string"
              }
            }
          },
          "notOnForm": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Only for /einvoices: invoice data the chosen form has no field for."
          }
        }
      },
      "Party": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "contactName": {
            "type": "string"
          },
          "street": {
            "type": "string"
          },
          "street2": {
            "type": "string"
          },
          "postCode": {
            "type": "string"
          },
          "town": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2, e.g. DE"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "vatId": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ]
      },
      "InvoiceLine": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "number",
            "default": 1
          },
          "netPrice": {
            "type": "number"
          },
          "lineTotal": {
            "type": "number",
            "description": "Default: quantity × netPrice"
          },
          "sellerAssignedId": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "netPrice"
        ]
      },
      "EInvoiceRequest": {
        "type": "object",
        "properties": {
          "formId": {
            "type": "string",
            "description": "Invoice form to use (default: the server's invoice form, zugferd)."
          },
          "action": {
            "type": "string",
            "enum": [
              "submit",
              "preview"
            ],
            "default": "submit",
            "description": "preview returns the filled PDF without processing or e-mails."
          },
          "invoice": {
            "type": "object",
            "properties": {
              "number": {
                "type": "string"
              },
              "date": {
                "type": "string",
                "format": "date",
                "description": "Default: today"
              },
              "currency": {
                "type": "string",
                "default": "EUR"
              },
              "note": {
                "type": "string"
              },
              "paymentTerms": {
                "type": "string"
              },
              "dueDate": {
                "type": "string",
                "format": "date"
              },
              "deliveryDate": {
                "type": "string",
                "format": "date"
              },
              "buyerReference": {
                "type": "string",
                "description": "XRechnung: Leitweg-ID"
              },
              "buyerOrderReference": {
                "type": "string"
              },
              "paymentReference": {
                "type": "string"
              },
              "taxPercent": {
                "type": "number"
              },
              "taxCategory": {
                "type": "string",
                "description": "UNTDID 5305: S (standard), Z (zero rated), E (exempt), AE (reverse charge), G (export outside the EU)"
              },
              "taxExemptionReason": {
                "type": "string"
              }
            },
            "required": [
              "number"
            ]
          },
          "seller": {
            "$ref": "#/components/schemas/Party"
          },
          "buyer": {
            "$ref": "#/components/schemas/Party"
          },
          "payment": {
            "type": "object",
            "properties": {
              "iban": {
                "type": "string"
              },
              "bic": {
                "type": "string"
              },
              "accountName": {
                "type": "string"
              }
            }
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/InvoiceLine"
            }
          },
          "totals": {
            "type": "object",
            "description": "Optional; calculated from the lines and taxPercent when missing.",
            "properties": {
              "lineTotal": {
                "type": "number"
              },
              "taxTotal": {
                "type": "number"
              },
              "grandTotal": {
                "type": "number"
              }
            }
          },
          "useIdentity": {
            "type": "boolean"
          },
          "returnPdf": {
            "type": "string",
            "enum": [
              "base64",
              "none",
              "binary"
            ]
          }
        },
        "required": [
          "invoice",
          "seller",
          "buyer",
          "items"
        ],
        "example": {
          "invoice": {
            "number": "2026-0042",
            "date": "2026-10-11",
            "currency": "EUR",
            "dueDate": "2026-10-25",
            "taxPercent": 19,
            "taxCategory": "S",
            "paymentTerms": "14 days net"
          },
          "seller": {
            "name": "Example Supplies GmbH",
            "street": "Musterstrasse 1",
            "postCode": "10115",
            "town": "Berlin",
            "country": "DE",
            "email": "billing@example.com",
            "vatId": "DE123456789"
          },
          "buyer": {
            "name": "Example Hotel AG",
            "street": "Seestrasse 1",
            "postCode": "12345",
            "town": "Musterstadt",
            "country": "DE",
            "email": "accounts@example.com"
          },
          "payment": {
            "iban": "DE02120300000000202051",
            "bic": "BYLADEM1001",
            "accountName": "Example Supplies GmbH"
          },
          "items": [
            {
              "name": "Consulting (hours)",
              "quantity": 4,
              "netPrice": 120
            },
            {
              "name": "Travel flat rate",
              "netPrice": 80
            }
          ]
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "wh_3f2a9c1d0b7e4a6c5d8e"
          },
          "formId": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "https address that receives the messages"
          },
          "description": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "submission.created"
              ]
            }
          },
          "active": {
            "type": "boolean"
          },
          "includePdf": {
            "type": "boolean",
            "description": "Add the submitted PDF (base64, up to 10 MB) to every message"
          },
          "failureEmails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "description": "Told when a message failed all 7 attempts"
          },
          "signing": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastDelivery": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "at": {
                "type": "string",
                "format": "date-time"
              },
              "result": {
                "type": "string",
                "enum": [
                  "delivered",
                  "failed"
                ]
              },
              "httpStatus": {
                "type": "integer"
              },
              "attempt": {
                "type": "integer"
              },
              "messageId": {
                "type": "string"
              },
              "error": {
                "type": "string"
              }
            }
          },
          "secretReadable": {
            "type": "boolean",
            "description": "false after the server's data folder was moved to another machine: rotate the secret"
          }
        }
      },
      "WebhookWithSecret": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Webhook"
          },
          {
            "type": "object",
            "properties": {
              "secret": {
                "type": "string",
                "description": "Signing secret whsec_... Shown only in this answer; store it safely.",
                "example": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
              }
            },
            "required": [
              "secret"
            ]
          }
        ]
      },
      "WebhookInput": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "https only; addresses in private networks are refused unless the server allows them"
          },
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "includePdf": {
            "type": "boolean",
            "default": false
          },
          "active": {
            "type": "boolean",
            "default": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "submission.created"
              ]
            }
          },
          "failureEmails": {
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "email"
                },
                "maxItems": 5
              },
              {
                "type": "string",
                "description": "separated by ; or ,"
              }
            ]
          }
        },
        "example": {
          "url": "https://crm.example.com/hooks/eforms",
          "description": "CRM import",
          "includePdf": true,
          "failureEmails": [
            "it@example.com"
          ]
        }
      },
      "SubmissionCreated": {
        "type": "object",
        "description": "Body of a submission.created message (Standard Webhooks envelope).",
        "properties": {
          "type": {
            "type": "string",
            "const": "submission.created"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "properties": {
              "formId": {
                "type": "string"
              },
              "submissionId": {
                "type": "string",
                "description": "Same ID the API returns for API submissions"
              },
              "reference": {
                "type": "string",
                "description": "Submission reference <form>/<counter>/<yy>"
              },
              "submittedAt": {
                "type": "string",
                "format": "date-time"
              },
              "values": {
                "type": "object",
                "additionalProperties": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "description": "Field name → value as submitted. Control fields of the web form are left out."
              },
              "pdf": {
                "type": "object",
                "description": "Only when includePdf is true",
                "properties": {
                  "fileName": {
                    "type": "string"
                  },
                  "contentType": {
                    "type": "string"
                  },
                  "size": {
                    "type": "integer"
                  },
                  "data": {
                    "type": "string",
                    "contentEncoding": "base64"
                  },
                  "omitted": {
                    "type": "string",
                    "enum": [
                      "too_large",
                      "not_available"
                    ]
                  }
                }
              }
            }
          }
        },
        "example": {
          "type": "submission.created",
          "timestamp": "2026-10-12T09:30:00Z",
          "data": {
            "formId": "contact",
            "submissionId": "5d0c2f4e8b1a4c7e9f3b2a1d6e5c4b3a",
            "reference": "contact/118/26",
            "submittedAt": "2026-10-12T09:30:00Z",
            "values": {
              "FirstName": "Erika",
              "Surname": "Muster",
              "Email": "erika@example.com"
            }
          }
        }
      },
      "TestMessage": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "webhook.test"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object",
            "properties": {
              "formId": {
                "type": "string"
              },
              "webhookId": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "TestResult": {
        "type": "object",
        "properties": {
          "delivered": {
            "type": "boolean"
          },
          "httpStatus": {
            "type": "integer"
          },
          "durationMs": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          }
        }
      },
      "PrefillRequest": {
        "type": "object",
        "properties": {
          "values": {
            "type": "object",
            "additionalProperties": {
              "type": [
                "string",
                "number",
                "boolean"
              ]
            },
            "description": "submitName → value; checked like a submission, but fields may stay empty"
          },
          "expiresInHours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Validity of the link (server maximum: setting Prefill\\MaxHours, default 2160 = 90 days)"
          },
          "lock": {
            "type": "boolean",
            "default": false,
            "description": "Make the prefilled text fields read-only in the browser (convenience, not a security control)"
          },
          "ignoreUnknownFields": {
            "type": "boolean",
            "default": false
          }
        },
        "required": [
          "values"
        ],
        "example": {
          "values": {
            "CustomerNo": "K-1042",
            "Surname": "Muster",
            "Email": "erika@example.com"
          },
          "expiresInHours": 72,
          "lock": true
        }
      },
      "PrefillLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "For DELETE; not the token"
          },
          "formId": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Send this link to the person; it contains the secret token"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "lock": {
            "type": "boolean"
          },
          "fields": {
            "type": "integer"
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "user": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "rateLimit": {
            "type": "object",
            "properties": {
              "limitPerMinute": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "remaining": {
                "type": "integer"
              },
              "resetSeconds": {
                "type": "integer"
              }
            }
          },
          "apiSubmissions": {
            "type": "object",
            "description": "user and admin only",
            "properties": {
              "today": {
                "type": "integer"
              },
              "limitPerDay": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "remaining": {
                "type": "integer"
              },
              "resetsAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "webhooks": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "queued": {
                "type": "integer",
                "description": "admin only"
              },
              "failedLast7Days": {
                "type": "integer",
                "description": "admin only"
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/": {
      "get": {
        "summary": "Service information",
        "description": "Name, version, OpenAPI URL and the trusted token issuers.",
        "tags": [
          "Service"
        ],
        "operationId": "getService",
        "responses": {
          "200": {
            "description": "Service information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/health": {
      "get": {
        "summary": "Health check",
        "description": "Returns ok when the API runs.",
        "tags": [
          "Service"
        ],
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/openapi": {
      "get": {
        "summary": "This OpenAPI description",
        "description": "Also at /api.ashx/v1/openapi.json.",
        "tags": [
          "Service"
        ],
        "operationId": "getOpenApi",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/field-types": {
      "get": {
        "summary": "Field types",
        "description": "All field types of the editor and whether they take a value.",
        "tags": [
          "Forms"
        ],
        "operationId": "listFieldTypes",
        "responses": {
          "200": {
            "description": "Field types",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fieldTypes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FieldType"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/me": {
      "get": {
        "summary": "Who am I",
        "description": "The identity, role and group the token stands for.",
        "tags": [
          "Service"
        ],
        "operationId": "getMe",
        "responses": {
          "200": {
            "description": "Identity",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/validation-rules": {
      "get": {
        "summary": "Validation rules",
        "description": "Named validation rules fields can use (e.g. email, IBAN, postcode).",
        "tags": [
          "Forms"
        ],
        "operationId": "listValidationRules",
        "responses": {
          "200": {
            "description": "Rules",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rules": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ValidationRule"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms": {
      "get": {
        "summary": "List forms",
        "description": "Forms this token may use. guest tokens see released forms only.",
        "tags": [
          "Forms"
        ],
        "operationId": "listForms",
        "responses": {
          "200": {
            "description": "Forms",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "forms": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Form"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "released",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Only released (true) or only draft (false) forms."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Text to search in ID and title."
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}": {
      "get": {
        "summary": "Form details",
        "description": "Settings, page count and links of one form.",
        "tags": [
          "Forms"
        ],
        "operationId": "getForm",
        "responses": {
          "200": {
            "description": "Form",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormDetail"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form, or not visible for this token.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/fields": {
      "get": {
        "summary": "List fields",
        "description": "All fields of the form with type, position, rules and options.",
        "tags": [
          "Forms"
        ],
        "operationId": "listFields",
        "responses": {
          "200": {
            "description": "Fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "formId": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "fields": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Field"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "inputOnly",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Only fields that take a value."
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/schema": {
      "get": {
        "summary": "JSON Schema of the values",
        "description": "JSON Schema 2020-12 of the values object of a submission (use it for code generation or AI agents).",
        "tags": [
          "Forms"
        ],
        "operationId": "getFormSchema",
        "responses": {
          "200": {
            "description": "JSON Schema",
            "content": {
              "application/schema+json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/pdf": {
      "get": {
        "summary": "Download the empty PDF form",
        "description": "The released PDF form.",
        "tags": [
          "Forms"
        ],
        "operationId": "getFormPdf",
        "responses": {
          "200": {
            "description": "PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The form is not released.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/validate": {
      "post": {
        "summary": "Validate values",
        "description": "Checks values like a submission would (required, options, length, rules) without submitting.",
        "tags": [
          "Submissions"
        ],
        "operationId": "validateValues",
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ValidationError"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/fill": {
      "post": {
        "summary": "Fill the PDF (no submission)",
        "description": "Returns the PDF filled with the values, like the Save button of the web form: no sealing, no e-mails. Required fields may be empty.",
        "tags": [
          "Submissions"
        ],
        "operationId": "fillForm",
        "responses": {
          "200": {
            "description": "Filled PDF",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionResult"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Submission-Id": {
                "description": "Only with Accept: application/pdf.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 10 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The form is not released.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid values (see errors).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "The form could not be processed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/submissions": {
      "post": {
        "summary": "Submit a form",
        "description": "Submits the values exactly like the web form: the PDF is created, sealed and signed (if configured), e-invoices are embedded, e-mails go to the business owner and to addresses in the data. Needs the role user or admin unless the server allows guests; the server has a daily cap of API submissions.",
        "tags": [
          "Submissions"
        ],
        "operationId": "submitForm",
        "responses": {
          "201": {
            "description": "Submitted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionResult"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Submission-Id": {
                "description": "Only with Accept: application/pdf.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 10 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The form is not released.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid values (see errors); nothing was submitted.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "The form could not be processed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/einvoices": {
      "post": {
        "summary": "Create an e-invoice (ZUGFeRD / Factur-X / XRechnung)",
        "description": "Maps a structured invoice to the server's invoice form and submits it. Totals are calculated when missing. The result is a PDF/A-3 with the EN 16931 XML embedded.",
        "tags": [
          "E-invoices"
        ],
        "operationId": "createEInvoice",
        "responses": {
          "201": {
            "description": "Invoice created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionResult"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Submission-Id": {
                "description": "Only with Accept: application/pdf.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "200": {
            "description": "preview: the filled invoice (not sent)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionResult"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Submission-Id": {
                "description": "Only with Accept: application/pdf.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 10 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Invoice form not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The invoice form is not released.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid invoice data.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "The invoice could not be processed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EInvoiceRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/usage": {
      "get": {
        "summary": "Usage and limits",
        "description": "The caller's rate limit, today's API submissions against the daily cap and (admins) the webhook queue. Every authenticated answer also carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.",
        "tags": [
          "Usage"
        ],
        "operationId": "getUsage",
        "responses": {
          "200": {
            "description": "Usage",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/webhooks": {
      "get": {
        "summary": "List webhooks",
        "description": "Needs the role admin (webhooks receive every value of every submission). ",
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhooks",
        "responses": {
          "200": {
            "description": "Webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "formId": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "post": {
        "summary": "Create a webhook",
        "description": "Needs the role admin (webhooks receive every value of every submission). The answer contains the signing secret, the only time it is shown. Messages are signed as Standard Webhooks (headers webhook-id, webhook-timestamp, webhook-signature).",
        "tags": [
          "Webhooks"
        ],
        "operationId": "createWebhook",
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookWithSecret"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The form has the maximum number of webhooks.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid url, events or failureEmails.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 10 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookInput"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/webhooks/{webhookId}": {
      "get": {
        "summary": "Webhook details",
        "description": "Needs the role admin (webhooks receive every value of every submission). Includes the result of the last delivery.",
        "tags": [
          "Webhooks"
        ],
        "operationId": "getWebhook",
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Change a webhook",
        "description": "Needs the role admin (webhooks receive every value of every submission). Only the fields sent are changed. PATCH and DELETE can also be sent as POST with the header X-HTTP-Method-Override.",
        "tags": [
          "Webhooks"
        ],
        "operationId": "updateWebhook",
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid values.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 10 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookInput"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Delete a webhook",
        "description": "Needs the role admin (webhooks receive every value of every submission). Messages still waiting for it are dropped. PATCH and DELETE can also be sent as POST with the header X-HTTP-Method-Override.",
        "tags": [
          "Webhooks"
        ],
        "operationId": "deleteWebhook",
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/webhooks/{webhookId}/test": {
      "post": {
        "summary": "Send a test message",
        "description": "Needs the role admin (webhooks receive every value of every submission). Sends webhook.test at once (no retries) and reports the receiver's answer.",
        "tags": [
          "Webhooks"
        ],
        "operationId": "testWebhook",
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestResult"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/webhooks/{webhookId}/rotate-secret": {
      "post": {
        "summary": "Rotate the signing secret",
        "description": "Needs the role admin (webhooks receive every value of every submission). The old secret stops working at once.",
        "tags": [
          "Webhooks"
        ],
        "operationId": "rotateWebhookSecret",
        "responses": {
          "200": {
            "description": "Webhook with the new secret",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookWithSecret"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form or webhook.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/prefill": {
      "post": {
        "summary": "Create a prefilled link",
        "description": "A link to the web form with these values filled in, e.g. for a customer who should only check and sign. The values stay on the server; the link carries a random token. Always needs the role user or admin. Values: at most 64 KB in total.",
        "tags": [
          "Prefilled links"
        ],
        "operationId": "createPrefillLink",
        "responses": {
          "201": {
            "description": "Link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrefillLink"
                }
              }
            }
          },
          "404": {
            "description": "Unknown form.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The form is not released.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid values.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 10 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrefillRequest"
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    },
    "/forms/{formId}/prefill/{prefillId}": {
      "delete": {
        "summary": "Revoke a prefilled link",
        "description": "The link opens the empty form from now on. PATCH and DELETE can also be sent as POST with the header X-HTTP-Method-Override.",
        "tags": [
          "Prefilled links"
        ],
        "operationId": "deletePrefillLink",
        "responses": {
          "204": {
            "description": "Revoked"
          },
          "404": {
            "description": "Unknown link.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. the body is not JSON).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired or untrusted bearer token. The WWW-Authenticate header says why.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid but not allowed (required scope or role missing, or the name belongs to a local account).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (per user, per address or the daily submission cap); see Retry-After.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Wrong HTTP method for this path.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Error on the server.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "API switched off, sign-in server not reachable, the internal address of the server is not configured, or the webhook configuration is busy (storage_busy).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "formId",
            "in": "path",
            "required": true,
            "description": "Form ID as shown in the form library (e.g. zugferd).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prefillId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-OIDC-Issuer",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only for opaque (non-JWT) tokens when several sign-in servers are configured: host of the server that issued the token."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ]
      }
    }
  },
  "webhooks": {
    "submission.created": {
      "post": {
        "summary": "A form was submitted",
        "description": "Sent to every active webhook of the form after the PDF was created (also for API submissions). Answer with 2xx within 15 seconds. Other answers and time-outs are retried after 1 min, 5 min, 30 min, 2 h, 6 h and 12 h; 410 Gone stops at once.",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "Message ID (msg_...); the same on every retry, use it to drop duplicates",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix seconds of this attempt; reject messages older than 5 minutes",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1,<base64 HMAC-SHA256 of id.timestamp.body> with the key = base64-decoded part of the secret after whsec_",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmissionCreated"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received (any 2xx)"
          },
          "410": {
            "description": "Stop sending this message"
          }
        }
      }
    },
    "webhook.test": {
      "post": {
        "summary": "Test message",
        "description": "Sent by POST /forms/{formId}/webhooks/{webhookId}/test.",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "Message ID (msg_...); the same on every retry, use it to drop duplicates",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "Unix seconds of this attempt; reject messages older than 5 minutes",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "v1,<base64 HMAC-SHA256 of id.timestamp.body> with the key = base64-decoded part of the secret after whsec_",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          }
        }
      }
    }
  }
}