{
  "openapi": "3.1.0",
  "info": {
    "title": "Rendlet PDF API",
    "version": "0.1.0",
    "description": "Render PDFs from HTML (headless Chromium) or from JSON + a built-in template (invoice, itinerary). Auth: Authorization: Bearer <key>. Get a free key via POST /v1/signup. Public test key: sandbox (5 renders/IP/day, 1 page, 50 KB HTML, watermarked)."
  },
  "servers": [
    {
      "url": "https://rendlet.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer"
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "HtmlRequest": {
        "type": "object",
        "required": [
          "html"
        ],
        "properties": {
          "html": {
            "type": "string",
            "maxLength": 2000000,
            "description": "Full HTML document. JavaScript is disabled; only data: and public https: assets load."
          },
          "options": {
            "type": "object",
            "properties": {
              "format": {
                "type": "string",
                "enum": [
                  "A4",
                  "Letter",
                  "Legal",
                  "A3",
                  "A5"
                ],
                "default": "A4"
              },
              "landscape": {
                "type": "boolean",
                "default": false
              },
              "margin": {
                "type": "string",
                "default": "12mm",
                "description": "CSS length applied to all sides"
              },
              "printBackground": {
                "type": "boolean",
                "default": true
              }
            }
          },
          "filename": {
            "type": "string"
          },
          "response": {
            "type": "string",
            "enum": [
              "binary",
              "base64"
            ],
            "default": "binary"
          }
        }
      },
      "TemplateRequest": {
        "type": "object",
        "required": [
          "template",
          "data"
        ],
        "properties": {
          "template": {
            "type": "string",
            "enum": [
              "invoice",
              "itinerary"
            ]
          },
          "data": {
            "type": "object",
            "description": "Template fields; see GET /v1/templates for full examples."
          },
          "filename": {
            "type": "string"
          },
          "response": {
            "type": "string",
            "enum": [
              "binary",
              "base64"
            ],
            "default": "binary"
          }
        }
      },
      "Base64Response": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string"
          },
          "pages": {
            "type": "integer"
          },
          "bytes": {
            "type": "integer"
          },
          "content_type": {
            "type": "string"
          },
          "base64": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          }
        }
      }
    }
  },
  "security": [
    {
      "bearer": []
    },
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/pdf": {
      "post": {
        "operationId": "renderPdf",
        "summary": "Render a PDF from HTML or from JSON + template",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/HtmlRequest"
                  },
                  {
                    "$ref": "#/components/schemas/TemplateRequest"
                  }
                ]
              },
              "examples": {
                "html": {
                  "value": {
                    "html": "<h1>Hello</h1><p>Rendered by Rendlet.</p>",
                    "options": {
                      "format": "A4"
                    }
                  }
                },
                "invoice": {
                  "value": {
                    "template": "invoice",
                    "data": {
                      "number": "INV-1001",
                      "currency": "USD",
                      "seller": {
                        "name": "Acme Studio"
                      },
                      "buyer": {
                        "name": "Globex"
                      },
                      "items": [
                        {
                          "description": "Design",
                          "qty": 1,
                          "unit_price": 500
                        }
                      ],
                      "tax_rate": 0.1
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PDF (binary) or JSON with base64 when response=base64. Headers: X-Pages, X-Plan, X-Quota-Limit, X-Quota-Remaining.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Base64Response"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing API key"
          },
          "403": {
            "description": "Invalid API key"
          },
          "413": {
            "description": "HTML too large or too many pages for plan"
          },
          "429": {
            "description": "Monthly quota exceeded"
          },
          "500": {
            "description": "Render failed"
          }
        }
      }
    },
    "/v1/templates": {
      "get": {
        "operationId": "listTemplates",
        "summary": "List JSON templates with example requests",
        "security": [],
        "responses": {
          "200": {
            "description": "Template list"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Plan and month-to-date usage for your key",
        "responses": {
          "200": {
            "description": "Usage"
          },
          "401": {
            "description": "Missing key"
          },
          "403": {
            "description": "Invalid key"
          }
        }
      }
    },
    "/v1/signup": {
      "post": {
        "operationId": "requestKey",
        "summary": "Issue a free API key (one per email; returned once; no email sent)",
        "security": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "plan": {
                    "type": "string",
                    "enum": [
                      "free",
                      "starter",
                      "pro",
                      "scale"
                    ]
                  },
                  "use_case": {
                    "type": "string"
                  },
                  "volume": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "400": {
            "description": "Invalid email"
          }
        }
      }
    },
    "/v1/checkout": {
      "post": {
        "summary": "Start a subscription checkout for your key",
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "plan"
                ],
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "starter",
                      "pro",
                      "scale"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{url} to open in a browser"
          },
          "401": {
            "description": "missing key"
          },
          "403": {
            "description": "invalid key"
          }
        }
      }
    }
  }
}