Quietforge

Pay-per-call API · x402

Quietforge Docs API

Document conversion, PDF text extraction, headless-browser rendering (URL or HTML to PNG / JPEG / PDF), an x402 service directory, a solver-verified sudoku generator, a book-interior typesetter, a crossword layout engine, a family tree chart engine (GEDCOM in, verified chart out) and a dataset quality auditor (duplicates, missing values, type consistency, outliers, PII-pattern counts) for agents and scripts. No account, no API key: each call is paid with a few cents of USDC on Base through the x402 protocol.

Endpoints

CallDoesPrice
POST /v1/convertText documents (docx, doc, odt, rtf, txt, md, html) → PDF, DOCX, ODT, HTML, TXT or PNG of page 1. Spreadsheets (xlsx, xls, ods, csv) → PDF, XLSX, ODS, CSV or PNG. Presentations (pptx, ppt, odp) → PDF, PPTX, ODP or PNG. Rendered with LibreOffice, so layout matches LibreOffice, not Word, pixel for pixel.$0.02
POST /v1/pdf/textText per page plus metadata from a digital PDF as JSON (no OCR).$0.005
POST /v1/renderRender a public URL or an HTML string in headless Chromium and return a PNG, JPEG or PDF. Viewport, device scale, full-page capture and paper size are yours to set.$0.01
GET /v1/x402/servicesSearch the x402 Service Index: health-probed pay-per-call endpoints with price, network, live status, latency and uptime across our last 20 probes. Filters q, network, alive, max_price_usd, source, limit, offset.$0.005
GET /v1/x402/services/{id}One indexed endpoint plus its last 20 probe samples.$0.002
POST /v1/sudoku1–20 classic 9×9 sudoku puzzles as JSON: proven-unique solution, 180° symmetric givens, difficulty graded by the human techniques a solver needed (easy / medium / hard / expert), deterministic per seed. See the Custom Sudoku Book page for what the same code prints.$0.01
POST /v1/sudoku/bookA finished print-ready sudoku book (30–60 puzzles): your title page and dedication, how-to page, section dividers, solutions; A4 + US Letter PDF, puzzles.json and README in one zip (base64). Standard or large print.$0.25
POST /v1/crossword8–30 of your own clue / answer pairs laid out into one connected freeform crossword (no black squares) as JSON: letter grid, every slot, standard row-major numbering, Across / Down clue lists. A verifier proves every run of letters is exactly one of your answers and each answer appears once; deterministic per seed. See the Custom Crossword Gift page for what the same code prints.$0.02
POST /v1/familytreeA family tree laid out as a descendant, ancestor (pedigree) or hourglass chart from people + families JSON or the text of a GEDCOM file (3–400 people, 2–10 generations): every person box with generation, x / y / width / height and formatted dates (living people shown as “living” by default), spouse and parent edges, chart bounds. A verifier proves no boxes overlap, every child is linked to its parents and every person in the subtree appears once. See the Custom Family Tree Chart page for what the same code prints.$0.02
POST /v1/familytree/pdfThe same chart as print-ready PDFs: 24×36 in and A3 single-sheet posters, plus US Letter and A4 files with a one-page overview, readable tiles with crop marks and overlap for taping, and an index of every person; classic or elegant typography; zip with chart.json, base64.$0.10
POST /v1/crossword/pdfThe same crossword as print-ready PDFs: puzzle page (title, subtitle, numbered grid, clues) plus an answer-key page in 8×10 in (frame-ready), A4 and US Letter, classic or elegant typography; zip with puzzle.json, base64.$0.10
POST /v1/typeset/outlineThe chapter structure our typesetter will use for a manuscript (chapters, words and scene breaks per chapter, unprintable characters, warnings) — check it before paying for a build.$0.01
POST /v1/typesetA prose manuscript (text or markdown) typeset into a print-ready paperback interior: PDF at 5×8, 5.25×8, 5.5×8.5, 6×9 or A5 with the inside gutter chosen from the final page count (KDP minimums), mirrored margins, running heads, page numbers, chapters on right-hand pages, front matter and contents; plus an editable Word twin and a layout report, zipped as base64. See the Book Interior Formatting page for a finished sample.$0.50
POST /v1/dataset-auditAudit a CSV or JSON-array dataset (up to 5 MB, 50,000 rows, 200 columns and 2,000,000 cells) as JSON: exact duplicate row count and up to 20 duplicate row indexes, per-column missing-value counts/percentages, inferred type with a mixed-type flag, class-imbalance ratio for low-cardinality categorical columns, IQR-based outlier counts for numeric columns, PII-pattern hit counts (email/phone/SSN/credit-card-like — counts only, matched values never returned), and one overall 0–100 quality_score. A free POST /v1/dataset-audit/preview (20 rows / 20 KB, unpaid) gives a teaser.$0.03
POST /v1/dataset-audit/pdfThe same audit as a compact PDF summary (score, top issues, per-column table, PII-pattern flags) zipped with report.json, base64.$0.08
GET /health, /, /docs, /.well-known/x402.jsonStatus, index, OpenAPI docs, discovery manifest (all fifteen paid routes).free

Base URL

The API has a permanent hostname, https://qf-api.quietforge-studio.workers.dev: a Cloudflare Worker at the edge that forwards every request, including the PAYMENT-SIGNATURE header, to our own machine. /docs-api/endpoint.json repeats it, and the manifest at <base>/.well-known/x402.json repeats the receiving address below so a client can check it is talking to us.

How a call works

Send the request without payment and you get HTTP 402 with a PAYMENT-REQUIRED header describing the price (USDC, Base mainnet, address below). Any x402 client signs a USDC transfer authorization for that amount and retries with a PAYMENT-SIGNATURE header; the facilitator settles it on-chain and the response comes back with the result. Clients: the x402 Python and TypeScript SDKs, x402-fetch, x402-axios, and most agent frameworks with x402 support.

# Python (pip install "x402[httpx,evm]")
import asyncio, base64
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact import ExactEvmScheme

payer = Account.from_key(YOUR_PRIVATE_KEY)          # a wallet holding a little USDC on Base
x402 = x402Client()
x402.register("eip155:*", ExactEvmScheme(signer=EthAccountSigner(payer)))

async def main():
    body = {"filename": "report.docx", "to": "pdf",
            "content_base64": base64.b64encode(open("report.docx", "rb").read()).decode()}
    async with x402HttpxClient(x402, timeout=90) as client:   # pays the $0.02 challenge and retries
        r = await client.post(BASE + "/v1/convert", json=body)
    open("report.pdf", "wb").write(base64.b64decode(r.json()["content_base64"]))
asyncio.run(main())

Render: URL or HTML → PNG / JPEG / PDF, $0.01 per call

POST /v1/render loads a page in headless Chromium and hands back the image or PDF as base64. Give it either a public url or an html string, never both.

{"url": "https://example.com", "format": "png",
 "width": 1280, "height": 800, "device_scale": 1,
 "full_page": false, "wait_until": "load", "wait_ms": 0}

{"html": "<h1>Invoice 104</h1>", "format": "pdf",
 "pdf_paper": "A4", "pdf_landscape": false}

-> {"format": "png", "content_type": "image/png", "bytes": 19288,
    "width": 1280, "height": 800, "final_url": "https://example.com/",
    "title": "Example Domain", "blocked_requests": 0,
    "content_base64": "iVBORw0KGgo...", "elapsed_ms": 1278}

Limits, plainly: format png, jpeg or pdf; viewport 320–1920 × 200–1080 CSS px; device_scale 1 or 2; jpeg_quality 1–100; wait_ms up to 5000; full_page is capped at 8000 px and applies to images, not PDF; HTML input up to 2 MB; the returned file is capped at 8 MB; 30 second timeout; one render at a time, so a second concurrent call gets a 503 and can retry. Set block_media: true to skip images, fonts and video for a faster, lighter render.

What it will not do: only public hosts on port 80 or 443 — loopback, private, link-local and cloud-metadata addresses are refused, and that check is re-applied to every redirect, iframe and sub-request inside the browser. No logins, cookies, scripting of the page or file downloads; each job runs in a fresh throwaway browser profile that is destroyed afterwards. We log the hostname, format, size and timing of a render and nothing else — never your HTML or your query strings. Render only pages you have the right to capture.

Inputs go in as base64 (up to 15 MB) or as a public URL. Conversions are capped at 35 seconds, two at a time (a busy converter answers 503 so you can retry). Files are processed in a temporary directory and deleted immediately; nothing is stored or logged beyond size and timing. Submit only files you have the right to process.

Sudoku: graded puzzles as JSON ($0.01) or a print-ready book ($0.25)

POST /v1/sudoku returns up to 20 puzzles per call. Each one is dug from a full grid in a 180° symmetric pattern while a bitmask solver proves the puzzle keeps exactly one solution, then solved again with only named human techniques — and that second solve, not the number of givens, decides the level. Easy needs singles only; medium adds naked pairs, pointing pairs and box-line reduction; hard adds naked triples, hidden pairs and X-wing; expert means those are not enough. The same seed and counts always give the same puzzles, so a daily puzzle can be reproduced.

{"counts": {"easy": 2, "medium": 2, "hard": 1}, "seed": 12345}

-> {"seed": 12345, "count": 5, "format": "puzzle/solution: 81 characters, row by row, 0 = empty",
    "puzzles": [{"n": 1, "level": "easy", "givens": 40, "techniques": ["naked single"],
                 "puzzle": "0402...", "solution": "3512..."}, ...], "elapsed_ms": 900}

POST /v1/sudoku/book takes name (up to 50 characters), an optional dedication (up to 200), counts totalling 30–60 and size (standard = four puzzles a page, large = two, large print) and returns a zip as base64: the book as A4 and US Letter PDFs, a puzzles.json with every grid and solution, and a README. A 60-puzzle book takes about 20 seconds; one book builds at a time, so a second concurrent call waits. Puzzles and books belong to the caller, commercial use included; we do not store inputs. Classic 9×9 only — no killer, samurai or 16×16 variants, and no puzzles that need chains or wings beyond X-wing.

POST /v1/typeset takes the manuscript as one string (format txt or md), title, author, an optional trim, chapter_numbers (words / roman / arabic / none), toc, copyright, dedication, epigraph, about_author and also_by, and returns a zip as base64: the interior PDF (Crimson Text embedded, justified and hyphenated, widows and orphans suppressed, smart quotes), the editable .docx twin and LAYOUT-REPORT.md with the page count, spine-width estimate, margins against KDP minimums and chapter start pages. Chapters are detected from Chapter N, # Title, roman-numeral lines or bare Prologue/Epilogue lines; scene breaks from * * * or #; run /v1/typeset/outline first ($0.01) to see the exact division. The text is never rewritten. A 30,000-word novel takes about three seconds; one book builds at a time. Prose only: no images, footnotes, tables, verse, lists or non-Latin scripts. Manuscripts are processed in a temporary directory and not stored.

POST /v1/crossword takes title (up to 40 characters), an optional subtitle (up to 90) and 8–30 entries of {answer, clue}: answers 3–15 letters (spaces, hyphens and accents are dropped in the grid and kept in the key, digits are refused), clues up to 110 characters, no duplicate answers. A backtracking placer tries several layouts and keeps the most compact one that passes the verifier, then numbers the starting cells in reading order. The answer is JSON: grid (rows of letters or null), slots, numbering, clues.across / clues.down, rows, cols, crossings. POST /v1/crossword/pdf adds style (classic or elegant) and sizes (any subset of 8x10, a4, letter) and returns a zip as base64: one two-page PDF per size (puzzle page and answer key) plus puzzle.json. A layout takes well under a second; a list that cannot be connected (very short answers with no shared letters) returns 422 with the reason instead of a broken grid. Freeform grids only: no newspaper-style black-square symmetry, no clue writing, Latin letters only.

POST /v1/familytree takes title (up to 60 characters), chart (descendant, ancestor or hourglass), an optional root person id, generations (2–10; an hourglass takes up to 5 in each direction) and the tree itself either as people ({id, name, sex, birth, death}, 3–400 of them) plus families ({id, husband, wife, children}, the GEDCOM FAM model) or as gedcom, the text of a GEDCOM 5.5 / 5.5.1 / 7.0 export from Ancestry, FamilySearch, MyHeritage or Gramps (up to 2,000,000 characters). Dates may be years or GEDCOM dates (“abt 1850” becomes “c. 1850”); with privatize_living true (the default) a person with no death date born within the last 100 years is shown as “living”. The engine places each person and spouse as a couple unit, hangs children under the couple they belong to, computes subtree widths so nothing overlaps, and returns nodes (id, name, dates, generation, x, y, w, h), edges (parent and spouse links) and the chart bounds; a verifier checks overlap, linkage and completeness before the answer is sent. POST /v1/familytree/pdf adds style (classic or elegant) and sizes (any subset of letter, a4, 24x36, a3) and returns a zip as base64: single-sheet posters for 24×36 and A3, and for Letter and A4 a one-page overview followed by readable tiles with crop marks and overlap plus an index of every person, together with chart.json. A 60-person chart takes a second or two; a subtree that cannot fit a single poster sheet at a readable size, an unknown root or a tree with a parent loop returns 422 with the reason. No research, no photos, no fan or circular charts, Latin, Greek and Cyrillic letters only.

Dataset quality audit: JSON ($0.03) or a PDF summary ($0.08)

POST /v1/dataset-audit takes data (CSV text, or a JSON array of flat objects; up to 5 MB, 50,000 rows, 200 columns and 2,000,000 cells — rows × columns, which is the binding limit on wide datasets: at 200 columns the row cap is effectively 10,000) and an optional format (auto-detected by default) and returns a structured report: exact duplicate rows (count plus up to 20 indexes), per-column missing-value counts and percentages, an inferred type per column with a mixed-type flag, a class-imbalance ratio for the lowest-cardinality categorical columns, IQR-based outlier counts for numeric columns, PII-pattern hit counts per column (email, phone-like, SSN-like, credit-card-like — the matched substrings themselves are never returned, only counts), and one overall quality_score from 0-100 (a documented heuristic for triage, not a certified data-quality or compliance metric). POST /v1/dataset-audit/pdf adds the same report as a compact PDF (usually one page, more for wide datasets) zipped with report.json as base64. A free, unpaid POST /v1/dataset-audit/preview runs the same checks on a small sample (20 rows / 20 KB) and returns row/column counts, the score and the top issue, so you can see the shape of the report before paying. Your data is held only in a temporary file for the duration of the request, deleted immediately after, and never logged or retained; the paid routes run in an isolated, resource-capped subprocess since the input is untrusted third-party data. A 50,000-row audit takes well under a second.

{"data": "id,name,email,age
1,Ana,ana@example.com,29
2,Ben,ben@example.com,41
2,Ben,ben@example.com,41
3,Cy,not-an-email,", "format": "csv"}

-> {"row_count": 4, "col_count": 4, "duplicate_row_count": 1, "duplicate_row_indexes": [2],
    "pii_flags": [{"column": "email", "pattern": "email", "match_count": 2}],
    "quality_score": 79,
    "issues": ["1 duplicate row(s) (25.0% of rows)", "Column 'age' is 25.0% missing",
               "Column 'email' looks like it may contain email-pattern data (2 match(es))"]}

MCP server: the free tools, for any MCP client

The same host also speaks the Model Context Protocol at https://qf-api.quietforge-studio.workers.dev/mcp (remote, streamable HTTP, stateless, no key) and is listed on the Official MCP Registry as io.github.quietforgestudio/x402-tools. Six read-only tools, all free: x402_search, x402_service and x402_index_stats read the x402 Service Index; x402_probe makes one live request to a public URL and reports whether it answers with an x402 challenge and at what price; sudoku_puzzle returns one solver-verified, technique-graded puzzle; quietforge_pricing lists the paid routes above and how to pay. Live probes are capped at 30 a minute and puzzles at 20 a minute across all clients, so a busy minute returns a polite error rather than a queue.

# Claude Code
claude mcp add --transport http quietforge https://qf-api.quietforge-studio.workers.dev/mcp

# Claude Desktop / Cursor / Windsurf (mcpServers block)
{"mcpServers": {"quietforge": {"url": "https://qf-api.quietforge-studio.workers.dev/mcp"}}}

# plain HTTP (one stateless JSON-RPC call)
curl -X POST https://qf-api.quietforge-studio.workers.dev/mcp -H "Content-Type: application/json"   -H "Accept: application/json, text/event-stream"   -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"x402_search","arguments":{"q":"weather","alive":true,"limit":5}}}'

Paying for the routes in the table still happens over plain HTTP with an x402 client, because an MCP client has no wallet; the MCP tools are the map, the x402 routes are the work.

Plain facts