{
  "openapi": "3.1.0",
  "info": {
    "title": "PDF1729 API",
    "version": "0.1.0"
  },
  "servers": [
    {
      "url": "https://pdf.1729.studio"
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "paths": {
    "/v1/pdf": {
      "post": {
        "summary": "Render HTML or a public URL to PDF",
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "html": {
                    "type": "string",
                    "description": "HTML; combined HTML and templates <=5 MiB"
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 4096
                  },
                  "allow_hosts": {
                    "type": "array",
                    "maxItems": 8,
                    "items": {
                      "type": "string"
                    },
                    "default": []
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "A4",
                      "Letter"
                    ],
                    "default": "A4"
                  },
                  "landscape": {
                    "type": "boolean",
                    "default": false
                  },
                  "print_background": {
                    "type": "boolean",
                    "default": false
                  },
                  "margins": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "top": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 2
                      },
                      "bottom": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 2
                      },
                      "left": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 2
                      },
                      "right": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 2
                      }
                    }
                  },
                  "header_template": {
                    "type": "string",
                    "description": "Maximum 64 KiB"
                  },
                  "footer_template": {
                    "type": "string",
                    "description": "Maximum 64 KiB"
                  },
                  "wait_for_selector": {
                    "type": "string",
                    "maxLength": 512
                  },
                  "wait_timeout_ms": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "default": 5000
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "html"
                    ],
                    "not": {
                      "required": [
                        "url"
                      ]
                    }
                  },
                  {
                    "required": [
                      "url"
                    ],
                    "not": {
                      "required": [
                        "html"
                      ]
                    }
                  }
                ]
              }
            },
            "text/html": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PDF, up to 20 MiB and 50 pages",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "HTML too large",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Render failed or resource denied WebSocket attempts are refused, including allowed hosts; failed renders do not consume quota.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Quota, rate or capacity limit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Invalid renderer response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Render worker or usage unavailable; worker failures include Retry-After: 2",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "responses": {
          "200": {
            "description": "Process alive; not worker readiness"
          }
        }
      }
    }
  }
}
