{
  "openapi": "3.1.0",
  "info": {
    "title": "makesPDF API",
    "version": "1.0.0",
    "description": "Deterministic PDF rendering API: GitHub-flavoured Markdown or a compact DSL to tagged, PDF/A-2A + PDF/UA-1 dual-compliant PDFs. Paid endpoints settle via x402 (USDC on Base) — no API keys.",
    "x-guidance": "POST /api/v1/markdown converts markdown to PDF ($0.01). POST /api/v1/render renders a template from templateId or inline DSL ($0.02). Both require an x402 payment: call unpaid to receive the 402 challenge (PAYMENT-REQUIRED header), sign an EIP-3009 USDC transfer, retry with the PAYMENT-SIGNATURE header. Free: GET /api/v1/templates?owner=library lists curated templates.",
    "contact": {
      "email": "jason@makespdf.com"
    }
  },
  "servers": [
    {
      "url": "https://makespdf.com"
    }
  ],
  "x-discovery": {
    "ownershipProofs": [
      "0xF4d2bC1034beE5eA270AcA773aEB97736d14fb31"
    ]
  },
  "security": [],
  "paths": {
    "/api/v1/markdown": {
      "summary": "Markdown to PDF (x402-paid)",
      "description": "Convert GitHub-flavoured Markdown to a tagged, accessible PDF — PDF/A-2A + PDF/UA-1 dual-compliant out of the box. Always returns a 402 challenge to unpaid requests.",
      "post": {
        "operationId": "markdownToPdf",
        "summary": "Convert Markdown to PDF",
        "tags": [
          "x402"
        ],
        "responses": {
          "200": {
            "description": "Rendered PDF (PDF/A-2A + PDF/UA-1 dual-compliant, tagged).",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required — x402 challenge (PAYMENT-REQUIRED header)."
          }
        },
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.010000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "markdown"
                ],
                "properties": {
                  "markdown": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200000,
                    "description": "GitHub-flavoured Markdown source (max 200KB)."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "pageSize": {
                        "type": "string",
                        "enum": [
                          "A3",
                          "A4",
                          "A5",
                          "Letter",
                          "Legal"
                        ]
                      },
                      "fontFamily": {
                        "type": "string",
                        "enum": [
                          "Inter",
                          "NotoSans"
                        ]
                      },
                      "fontSize": {
                        "type": "number",
                        "minimum": 6,
                        "maximum": 24
                      },
                      "margins": {
                        "type": "array",
                        "minItems": 4,
                        "maxItems": 4,
                        "items": {
                          "type": "number"
                        },
                        "description": "[top, right, bottom, left] in points."
                      },
                      "title": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "theme": {
                        "type": "string",
                        "enum": [
                          "default",
                          "github"
                        ]
                      }
                    },
                    "description": "Rendering options. Omit for defaults."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/render": {
      "summary": "Render template to PDF (x402-paid)",
      "description": "Generate a PDF from structured data — no source document needed. Supply data plus a curated-library template id (or inline DSL); output is a tagged, accessible PDF/UA-1 + PDF/A-2A document. Always returns a 402 challenge to unpaid requests.",
      "post": {
        "operationId": "renderPdf",
        "summary": "Render a template (templateId or inline DSL) to PDF",
        "tags": [
          "x402"
        ],
        "responses": {
          "200": {
            "description": "Rendered PDF (PDF/A-2A + PDF/UA-1 dual-compliant, tagged).",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required — x402 challenge (PAYMENT-REQUIRED header)."
          }
        },
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.020000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "templateId"
                    ],
                    "properties": {
                      "templateId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
                        "description": "Curated-library or saved template id. Browse the library at GET /api/v1/templates?owner=library."
                      },
                      "data": {
                        "type": "object",
                        "description": "Values substituted into {{placeholders}}."
                      },
                      "options": {
                        "type": "object",
                        "properties": {
                          "title": {
                            "type": "string",
                            "maxLength": 200
                          }
                        }
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "dsl"
                    ],
                    "properties": {
                      "dsl": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 512000,
                        "description": "Builder DSL script (bring your own template). Reference: https://makespdf.com/skills/pdf-template-author.md"
                      },
                      "data": {
                        "type": "object",
                        "description": "Values substituted into {{placeholders}}."
                      },
                      "options": {
                        "type": "object",
                        "properties": {
                          "title": {
                            "type": "string",
                            "maxLength": 200
                          }
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/templates": {
      "summary": "List templates",
      "description": "List templates under the read predicate — curated library rows are world-readable.",
      "get": {
        "operationId": "listTemplates",
        "summary": "List templates",
        "tags": [
          "public"
        ],
        "responses": {
          "200": {
            "description": "Metadata for visible templates."
          },
          "4XX": {
            "description": "Error response (e.g. 401 unauthenticated, 429 rate-limited)."
          }
        },
        "security": []
      }
    },
    "/api/v1/md": {
      "summary": "Markdown to PDF (free carve-out)",
      "description": "Markdown to PDF with an anonymous free carve-out while the promo flag is enabled. Not x402-annotated — use /api/v1/markdown for x402 discovery.",
      "get": {
        "operationId": "mdHelp",
        "summary": "Markdown endpoint info",
        "tags": [
          "public"
        ],
        "responses": {
          "200": {
            "description": "Markdown rendering service."
          },
          "4XX": {
            "description": "Error response (e.g. 401 unauthenticated, 429 rate-limited)."
          }
        },
        "security": []
      }
    },
    "/api/v1/artifacts": {
      "summary": "List render artifacts",
      "description": "List the caller's recent render artifacts (metadata only).",
      "get": {
        "operationId": "listArtifacts",
        "summary": "List artifacts",
        "tags": [
          "public"
        ],
        "responses": {
          "200": {
            "description": "Metadata for the caller's artifacts."
          },
          "4XX": {
            "description": "Error response (e.g. 401 unauthenticated, 429 rate-limited)."
          }
        },
        "security": []
      }
    },
    "/api/v1/md/validate": {
      "summary": "Validate markdown",
      "description": "Check markdown for PDF/UA-1 accessibility issues (heading hierarchy, missing alt text) without rendering.",
      "post": {
        "operationId": "validateMarkdown",
        "summary": "Validate markdown accessibility",
        "tags": [
          "public"
        ],
        "responses": {
          "200": {
            "description": "{ valid, issues, summary }"
          },
          "4XX": {
            "description": "Error response (e.g. 401 unauthenticated, 429 rate-limited)."
          }
        },
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "markdown"
                ],
                "properties": {
                  "markdown": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/preview/validate": {
      "summary": "Validate DSL template",
      "description": "Check a DSL template for structure and accessibility issues without rendering.",
      "post": {
        "operationId": "validateTemplate",
        "summary": "Validate a DSL template",
        "tags": [
          "public"
        ],
        "responses": {
          "200": {
            "description": "{ valid, issues, summary }"
          },
          "4XX": {
            "description": "Error response (e.g. 401 unauthenticated, 429 rate-limited)."
          }
        },
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "dsl"
                ],
                "properties": {
                  "dsl": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
