{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.pastetoprint.com/api/document-schema/v1/schema.json",
  "$comment": "SPDX-License-Identifier: MIT; Copyright (c) 2026 pasteToPrint contributors. See /PTDF-LICENSE.md. Keywords prefixed x-ptdf- are required PTDF assertions implemented by the reference validators.",
  "title": "PTDF 1.0 — pasteToPrint Document Format",
  "description": "PTDF 1.0 is the public name of pasteToPrint Document Schema v1. Its stable wire identifier is ptp.document/1. The format is rendered by pasteToPrint without accepting HTML or CSS.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "blocks"
  ],
  "properties": {
    "schemaVersion": {
      "const": "ptp.document/1"
    },
    "title": {
      "type": "string",
      "maxLength": 200
    },
    "locale": {
      "type": "string",
      "maxLength": 35,
      "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*(?![\\s\\S])",
      "default": "sk"
    },
    "paper": {
      "$ref": "#/$defs/paper"
    },
    "template": {
      "type": "string",
      "maxLength": 64,
      "description": "Stable presentation preset ID from pasteToPrint Template Catalog v1 at /api/v2/templates. The preset never injects document content.",
      "enum": [
        "blank",
        "coloring_dinosaur",
        "coloring_unicorn",
        "coloring_space",
        "coloring_ocean",
        "coloring_farm",
        "coloring_forest",
        "business",
        "invoice",
        "offer",
        "contract",
        "order",
        "order_modern",
        "price_offer",
        "price_offer_modern",
        "invoice_basis",
        "business_letter",
        "delivery_note",
        "service",
        "handover",
        "work_report",
        "meeting",
        "note",
        "request",
        "complaint",
        "declaration",
        "power_authority",
        "termination_notice",
        "withdrawal",
        "gdpr_consent"
      ],
      "default": "blank"
    },
    "blocks": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "$ref": "#/$defs/block"
      }
    }
  },
  "$defs": {
    "paper": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "string",
          "enum": [
            "A4",
            "A5",
            "A6",
            "LETTER",
            "LEGAL"
          ],
          "default": "A4"
        },
        "orientation": {
          "type": "string",
          "enum": [
            "portrait",
            "landscape"
          ],
          "default": "portrait"
        }
      }
    },
    "run": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "text"
      ],
      "properties": {
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        "bold": {
          "type": "boolean"
        },
        "italic": {
          "type": "boolean"
        },
        "underline": {
          "type": "boolean"
        },
        "strike": {
          "type": "boolean"
        },
        "code": {
          "type": "boolean"
        },
        "subscript": {
          "type": "boolean"
        },
        "superscript": {
          "type": "boolean"
        },
        "link": {
          "type": "string",
          "maxLength": 2048,
          "pattern": "^(?:https?://[^\\s\\u0000-\\u001f\\u007f/?#]+[^\\s\\u0000-\\u001f\\u007f]*|mailto:[^\\s\\u0000-\\u001f\\u007f]+|tel:[^\\s\\u0000-\\u001f\\u007f]+)(?![\\s\\S])"
        }
      },
      "not": {
        "required": [
          "subscript",
          "superscript"
        ],
        "properties": {
          "subscript": {
            "const": true
          },
          "superscript": {
            "const": true
          }
        }
      }
    },
    "textContent": {
      "oneOf": [
        {
          "required": [
            "text"
          ],
          "properties": {
            "text": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100000
            }
          }
        },
        {
          "required": [
            "runs"
          ],
          "properties": {
            "runs": {
              "type": "array",
              "minItems": 1,
              "maxItems": 500,
              "items": {
                "$ref": "#/$defs/run"
              }
            }
          }
        }
      ]
    },
    "paragraph": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "paragraph"
        },
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        "runs": {
          "type": "array",
          "minItems": 1,
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/run"
          }
        },
        "align": {
          "$ref": "#/$defs/alignment"
        }
      },
      "oneOf": [
        {
          "required": [
            "text"
          ]
        },
        {
          "required": [
            "runs"
          ]
        }
      ]
    },
    "heading": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "level"
      ],
      "properties": {
        "type": {
          "const": "heading"
        },
        "level": {
          "type": "integer",
          "minimum": 1,
          "maximum": 3
        },
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        "runs": {
          "type": "array",
          "minItems": 1,
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/run"
          }
        },
        "align": {
          "$ref": "#/$defs/alignment"
        }
      },
      "oneOf": [
        {
          "required": [
            "text"
          ]
        },
        {
          "required": [
            "runs"
          ]
        }
      ]
    },
    "quote": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "quote"
        },
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        "runs": {
          "type": "array",
          "minItems": 1,
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/run"
          }
        },
        "align": {
          "$ref": "#/$defs/alignment"
        }
      },
      "oneOf": [
        {
          "required": [
            "text"
          ]
        },
        {
          "required": [
            "runs"
          ]
        }
      ]
    },
    "listItem": {
      "oneOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "text": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100000
            },
            "runs": {
              "type": "array",
              "minItems": 1,
              "maxItems": 500,
              "items": {
                "$ref": "#/$defs/run"
              }
            },
            "checked": {
              "type": "boolean"
            }
          },
          "oneOf": [
            {
              "required": [
                "text"
              ]
            },
            {
              "required": [
                "runs"
              ]
            }
          ]
        }
      ]
    },
    "list": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "items"
      ],
      "properties": {
        "type": {
          "const": "list"
        },
        "style": {
          "type": "string",
          "enum": [
            "bullet",
            "number",
            "check"
          ],
          "default": "bullet"
        },
        "items": {
          "type": "array",
          "minItems": 1,
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/listItem"
          }
        }
      }
    },
    "tableCellObject": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "text": {
          "type": "string",
          "maxLength": 100000
        },
        "runs": {
          "type": "array",
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/run"
          }
        },
        "colspan": {
          "type": "integer",
          "minimum": 1,
          "maximum": 20
        },
        "rowspan": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200
        }
      },
      "oneOf": [
        {
          "required": [
            "text"
          ]
        },
        {
          "required": [
            "runs"
          ]
        }
      ]
    },
    "tableCell": {
      "oneOf": [
        {
          "type": "string",
          "maxLength": 100000
        },
        {
          "$ref": "#/$defs/tableCellObject"
        }
      ]
    },
    "table": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "rows"
      ],
      "properties": {
        "type": {
          "const": "table"
        },
        "columns": {
          "type": "array",
          "minItems": 1,
          "maxItems": 20,
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          }
        },
        "rows": {
          "type": "array",
          "minItems": 1,
          "maxItems": 200,
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/$defs/tableCell"
            }
          }
        }
      }
    },
    "code": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "text"
      ],
      "properties": {
        "type": {
          "const": "code"
        },
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        "language": {
          "type": "string",
          "maxLength": 40
        }
      }
    },
    "image": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "dataUrl"
      ],
      "properties": {
        "type": {
          "const": "image"
        },
        "dataUrl": {
          "type": "string",
          "maxLength": 1500000,
          "pattern": "^data:image/(?:png|jpe?g|webp|gif|bmp);base64,[A-Za-z0-9+/]+={0,2}(?![\\s\\S])",
          "x-ptdf-validBase64": true
        },
        "alt": {
          "type": "string",
          "maxLength": 300
        },
        "caption": {
          "type": "string",
          "maxLength": 300
        },
        "scale": {
          "type": "integer",
          "enum": [
            25,
            50,
            75,
            100
          ],
          "default": 100
        },
        "align": {
          "type": "string",
          "enum": [
            "left",
            "center",
            "right"
          ],
          "default": "center"
        }
      }
    },
    "keyValueEntry": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "key",
        "value"
      ],
      "properties": {
        "key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "value": {
          "type": "string",
          "maxLength": 5000
        }
      }
    },
    "keyValue": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "entries"
      ],
      "properties": {
        "type": {
          "const": "key_value"
        },
        "entries": {
          "type": "array",
          "minItems": 1,
          "maxItems": 100,
          "items": {
            "$ref": "#/$defs/keyValueEntry"
          }
        }
      }
    },
    "addressValue": {
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "street": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "street2": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "city": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        "region": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        "postalCode": {
          "type": "string",
          "minLength": 1,
          "maxLength": 32
        },
        "country": {
          "type": "string",
          "pattern": "^[A-Za-z]{2}(?![\\s\\S])"
        }
      }
    },
    "address": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "minProperties": 2,
      "properties": {
        "type": {
          "const": "address"
        },
        "street": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "street2": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "city": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        "region": {
          "type": "string",
          "minLength": 1,
          "maxLength": 160
        },
        "postalCode": {
          "type": "string",
          "minLength": 1,
          "maxLength": 32
        },
        "country": {
          "type": "string",
          "pattern": "^[A-Za-z]{2}(?![\\s\\S])"
        }
      }
    },
    "party": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "name"
      ],
      "properties": {
        "type": {
          "const": "party"
        },
        "role": {
          "type": "string",
          "enum": [
            "supplier",
            "customer",
            "issuer",
            "recipient",
            "other"
          ],
          "default": "other"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "companyId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "taxId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "vatId": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "email": {
          "type": "string",
          "maxLength": 254,
          "pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+(?![\\s\\S])"
        },
        "phone": {
          "type": "string",
          "minLength": 1,
          "maxLength": 80
        },
        "address": {
          "$ref": "#/$defs/addressValue"
        }
      }
    },
    "date": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "value"
      ],
      "properties": {
        "type": {
          "const": "date"
        },
        "value": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}(?![\\s\\S])",
          "x-ptdf-calendarDate": true
        },
        "label": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        }
      }
    },
    "money": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "amount",
        "currency"
      ],
      "properties": {
        "type": {
          "const": "money"
        },
        "amount": {
          "type": "string",
          "maxLength": 18,
          "pattern": "^-?(?:0|[1-9]\\d{0,11})(?:\\.\\d{1,4})?(?![\\s\\S])"
        },
        "currency": {
          "type": "string",
          "pattern": "^[A-Za-z]{3}(?![\\s\\S])"
        },
        "label": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        }
      }
    },
    "spacer": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "spacer"
        },
        "size": {
          "type": "string",
          "enum": [
            "small",
            "medium",
            "large"
          ],
          "default": "medium"
        }
      }
    },
    "logo": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "dataUrl"
      ],
      "properties": {
        "type": {
          "const": "logo"
        },
        "dataUrl": {
          "type": "string",
          "maxLength": 1500000,
          "pattern": "^data:image/(?:png|jpe?g|webp|gif|bmp);base64,[A-Za-z0-9+/]+={0,2}(?![\\s\\S])",
          "x-ptdf-validBase64": true
        },
        "alt": {
          "type": "string",
          "maxLength": 300
        },
        "scale": {
          "type": "integer",
          "enum": [
            25,
            50,
            75,
            100
          ],
          "default": 100
        },
        "align": {
          "type": "string",
          "enum": [
            "left",
            "center",
            "right"
          ],
          "default": "center"
        }
      }
    },
    "qrCode": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "value"
      ],
      "properties": {
        "type": {
          "const": "qr_code"
        },
        "value": {
          "type": "string",
          "minLength": 1,
          "maxLength": 134,
          "x-ptdf-maxUtf8Bytes": 134
        },
        "label": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "size": {
          "type": "string",
          "enum": [
            "small",
            "medium",
            "large"
          ],
          "default": "medium"
        },
        "align": {
          "type": "string",
          "enum": [
            "left",
            "center",
            "right"
          ],
          "default": "center"
        }
      }
    },
    "checkbox": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "label"
      ],
      "properties": {
        "type": {
          "const": "checkbox"
        },
        "label": {
          "type": "string",
          "minLength": 1,
          "maxLength": 1000
        },
        "checked": {
          "type": "boolean",
          "default": false
        }
      }
    },
    "signature": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type",
        "label"
      ],
      "properties": {
        "type": {
          "const": "signature"
        },
        "label": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "role": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "date": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}(?![\\s\\S])",
          "x-ptdf-calendarDate": true
        }
      }
    },
    "notice": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "notice"
        },
        "kind": {
          "type": "string",
          "enum": [
            "info",
            "success",
            "warning",
            "danger"
          ],
          "default": "info"
        },
        "title": {
          "type": "string",
          "minLength": 1,
          "maxLength": 300
        },
        "text": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100000
        },
        "runs": {
          "type": "array",
          "minItems": 1,
          "maxItems": 500,
          "items": {
            "$ref": "#/$defs/run"
          }
        }
      },
      "oneOf": [
        {
          "required": [
            "text"
          ]
        },
        {
          "required": [
            "runs"
          ]
        }
      ]
    },
    "divider": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "divider"
        }
      }
    },
    "pageBreak": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "page_break"
        }
      }
    },
    "alignment": {
      "type": "string",
      "enum": [
        "left",
        "center",
        "right",
        "justify"
      ]
    },
    "block": {
      "oneOf": [
        {
          "$ref": "#/$defs/paragraph"
        },
        {
          "$ref": "#/$defs/heading"
        },
        {
          "$ref": "#/$defs/list"
        },
        {
          "$ref": "#/$defs/table"
        },
        {
          "$ref": "#/$defs/quote"
        },
        {
          "$ref": "#/$defs/code"
        },
        {
          "$ref": "#/$defs/image"
        },
        {
          "$ref": "#/$defs/keyValue"
        },
        {
          "$ref": "#/$defs/party"
        },
        {
          "$ref": "#/$defs/address"
        },
        {
          "$ref": "#/$defs/date"
        },
        {
          "$ref": "#/$defs/money"
        },
        {
          "$ref": "#/$defs/spacer"
        },
        {
          "$ref": "#/$defs/logo"
        },
        {
          "$ref": "#/$defs/qrCode"
        },
        {
          "$ref": "#/$defs/checkbox"
        },
        {
          "$ref": "#/$defs/signature"
        },
        {
          "$ref": "#/$defs/notice"
        },
        {
          "$ref": "#/$defs/divider"
        },
        {
          "$ref": "#/$defs/pageBreak"
        }
      ]
    }
  }
}
