{
  "openapi": "3.1.0",
  "info": {
    "title": "NoJunk Document",
    "version": "1.0.0",
    "description": "Pay-per-call document reading for agents: convert a PDF, Word, Excel, OpenDocument, CSV, Apple Numbers, HTML, XML or image file (by public URL or base64) into clean Markdown you can reason over. One cent per document; you are only charged when a conversion is returned.",
    "x-guidance": "One POST endpoint paid per call in USDC on Base via x402 (you are only charged when a conversion is returned; every 4xx/5xx is free). If you need to read a PDF, Word/Excel/OpenDocument file, CSV, Apple Numbers, HTML or XML page, or an image (PNG/JPEG/WebP/SVG) and only have a link or the raw bytes, POST /convert {url} or {file_base64, filename?, content_type?}, max_chars? (1000-400000) for $0.01 and get {name, mime_type, bytes, markdown, truncated, total_chars, tokens, word_count, pages_hint, source_url, converted_at}. url must be a public http(s) URL serving a supported file up to 20971520 bytes (private/loopback hosts refused, 20 s timeout, 3 redirects re-checked). PDFs and images are detected from their bytes; for ZIP-based Office files sent as base64 include filename (e.g. \"deck.xlsx\") or content_type. Markdown is capped at 400000 characters (truncated=true when cut), so pass a smaller max_chars when you only need the start. Errors, all unpaid: 400 bad input, 413 body over 29360128 bytes or file over 20971520 bytes, 415 unsupported type, 422 file could not be converted (corrupt or password-protected), 502 url unreachable or converter unavailable. Best for: reading papers, filings, manuals, invoices, spreadsheets and slides behind a link; turning scanned-looking PDFs into text; extracting tables from Excel; pulling the article out of a web page."
  },
  "servers": [
    {
      "url": "https://nojunk-document.mick8511.workers.dev"
    }
  ],
  "paths": {
    "/convert": {
      "post": {
        "operationId": "convertDocument",
        "summary": "Convert a document (PDF, Office, spreadsheet, HTML, image) to Markdown",
        "tags": [
          "Documents",
          "PDF",
          "Markdown",
          "Extraction"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.010000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "Public http(s) URL of the document (max 20971520 bytes, 20 s fetch timeout, up to 3 redirects). Private, loopback and internal hosts are refused. The type is taken from magic bytes, then the URL path extension, then the Content-Type header."
                  },
                  "file_base64": {
                    "type": "string",
                    "description": "File bytes as base64 (standard or url-safe, data: prefix allowed), max 20971520 decoded bytes"
                  },
                  "filename": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Original filename with extension. PDFs and images are recognized from their bytes; ZIP-based Office/OpenDocument files (docx, xlsx, xlsm, xlsb, ods, odt, numbers) need this or content_type."
                  },
                  "content_type": {
                    "type": "string",
                    "description": "MIME type of the file, used when no usable extension is available"
                  },
                  "max_chars": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 400000,
                    "default": 400000,
                    "description": "Cap on the number of markdown characters returned; truncated is true when the cap cut the text"
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "url"
                    ]
                  },
                  {
                    "required": [
                      "file_base64"
                    ]
                  }
                ]
              },
              "example": {
                "url": "https://pdfobject.com/pdf/sample.pdf"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The document as Markdown",
            "headers": {
              "PAYMENT-RESPONSE": {
                "description": "Base64 x402 settlement receipt",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Filename the document was converted as (extension reflects the detected type)"
                    },
                    "mime_type": {
                      "type": "string",
                      "description": "MIME type of the source document"
                    },
                    "bytes": {
                      "type": "integer",
                      "description": "Size of the source document in bytes"
                    },
                    "markdown": {
                      "type": "string",
                      "description": "The document as Markdown (at most max_chars, default 400000 characters)"
                    },
                    "truncated": {
                      "type": "boolean",
                      "description": "True when markdown was cut at max_chars"
                    },
                    "total_chars": {
                      "type": "integer",
                      "description": "Length of the full conversion before any truncation"
                    },
                    "tokens": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Token count reported by the converter"
                    },
                    "word_count": {
                      "type": "integer",
                      "description": "Word count of the full conversion"
                    },
                    "pages_hint": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Number of page markers found in the markdown, or null when the converter emitted none"
                    },
                    "source_url": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The url that was fetched, or null for base64 input"
                    },
                    "converted_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "name",
                    "mime_type",
                    "bytes",
                    "markdown",
                    "truncated",
                    "total_chars",
                    "tokens",
                    "word_count",
                    "pages_hint",
                    "source_url",
                    "converted_at"
                  ]
                },
                "example": {
                  "name": "sample.pdf",
                  "mime_type": "application/pdf",
                  "bytes": 18810,
                  "markdown": "# sample.pdf\n## Metadata\n- PDFFormatVersion=1.3\n- IsLinearized=false\n- IsAcroFormPresent=false\n- Title=sample\n- Author=Philip Hutchison\n## Contents\n### Page 1\nSample PDF\nThis is a simple PDF file. Fun fun fun.\nLorem ipsum dolor sit amet, consectetuer adipiscing elit. ...",
                  "truncated": false,
                  "total_chars": 3100,
                  "tokens": 780,
                  "word_count": 430,
                  "pages_hint": 1,
                  "source_url": "https://pdfobject.com/pdf/sample.pdf",
                  "converted_at": "2026-10-18T17:49:53.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input: missing url/file_base64, bad URL, private or internal host, bad base64, bad max_chars (no charge)"
          },
          "402": {
            "description": "Payment Required: the PAYMENT-REQUIRED header carries the base64 x402 requirements; also returned when payment verification or settlement fails (no charge)"
          },
          "413": {
            "description": "Request body larger than 29360128 bytes, or file larger than 20971520 bytes (no charge)"
          },
          "415": {
            "description": "Unsupported file type; supported: PDF, DOCX, XLSX, XLSM, XLSB, XLS, ODS, ODT, CSV, Apple Numbers, HTML, XML, Markdown, plain text, PNG, JPEG, WebP, SVG (no charge)"
          },
          "422": {
            "description": "The file was recognized but could not be converted (corrupt, encrypted or empty) (no charge)"
          },
          "502": {
            "description": "url unreachable, non-2xx, empty, redirected to a blocked address or too many times; or the converter is temporarily unavailable (no charge)"
          }
        }
      }
    }
  }
}