# Document Operation API — full description > A stateless document-operation API. Send markup or a file over HTTP, get bytes back. Nothing is stored: work happens in a tmpfs workspace that is unlinked before the response is sent. Paid for with one-time credit packs that never expire — no subscription, and no feature gating between tiers. ## What it does **Markup in, PDF out.** Three input formats: **Markdown**, **HTML** and **Typst**. Page size, margins, orientation, headers and footers are request parameters. Headers and footers substitute `{page}` and `{pages}`. Typst is the differentiator: it has 55k GitHub stars and no hosted render API anywhere else. Markdown and HTML are the volume. **PDF in, PDF out.** Eight operations on an existing document: merge, split, compress, rotate, watermark, reorder, extract-pages and unlock. Upload as `multipart/form-data`; `split` returns a ZIP because it is the one operation that produces many files. Watermarking is decoration — the text sits above content that is still selectable underneath — and unlocking requires the document's password rather than attempting to recover one. ## What it does not do - **It does not store your files.** There is no object storage in the request path. Input is written to a tmpfs workspace, the operation runs, the bytes are returned, and the workspace is unlinked before the response completes — including when a request is cancelled. - **It does not have a subscription.** Credits are bought once and never expire. - **It does not gate features by tier.** Every pack unlocks the same API. - **It does not charge for failures.** Credits are held before an operation and settled after. A failure refunds in full, automatically, per item in a batch. ## The 11 products Every operation below is on the same wallet and the same key. F148: this section exists so an agent can decide whether to call an endpoint, and what it will cost, without a second fetch. ### 1. Markup to PDF Markdown, HTML or Typst in, PDF bytes out, with stored templates so a repeated document is an id and a data object. | Endpoint | Credits | |---|---| | POST /api/v1/render | 1 per document, +1 per 10 pages over 10 | | POST /api/v1/render/batch | 1 per document, failures refunded | | POST /api/v1/render/from-template | 1 per document | | /api/v1/templates | free | ### 2. Private document operations Redaction that removes the glyphs and then proves they are gone, and metadata stripping. Nothing is stored. | Endpoint | Credits | |---|---| | POST /api/v1/redact | 2 per operation | | POST /api/v1/metadata/strip | 1 per operation | | POST /api/v1/metadata/inspect | free, no API key | ### 3. Any document to markdown PDFs, Office files and scans to clean markdown with heading-aware chunks. Each page is classified before it is charged, so text pages cost a tenth of a scanned one. | Endpoint | Credits | |---|---| | POST /api/v1/parse | 1 per 10 text pages, 1 per OCR page | | POST /api/v1/parse/batch | same rates, failures refunded | ### 4. Evidence-grade web capture A screenshot, PDF, WARC and signed manifest of a page, timestamped with RFC-3161, and a verification URL that needs no account. | Endpoint | Credits | |---|---| | POST /api/v1/capture | 1, or 5 retained with a timestamp and manifest | | GET /api/v1/capture/{id}/verify | free, no API key | | POST /api/v1/capture/schedule | priced per capture | ### 5. PDF operations Merge, split, compress, rotate, watermark, reorder, extract pages and unlock, one credit each. | Endpoint | Credits | |---|---| | POST /api/v1/pdf/merge | 1 per operation | | POST /api/v1/pdf/split | 1 per operation, returns a ZIP | | POST /api/v1/pdf/compress | 1 per operation | | POST /api/v1/pdf/rotate | 1 per operation | | POST /api/v1/pdf/watermark | 1 per operation | | POST /api/v1/pdf/reorder | 1 per operation | | POST /api/v1/pdf/extract-pages | 1 per operation | | POST /api/v1/pdf/unlock | 1 per operation, password required | ### 6. Web page to markdown or PDF One named page, rendered with adverts, cookie walls and trackers blocked, then reduced to its main content. Not a crawler: it follows no links. | Endpoint | Credits | |---|---| | POST /api/v1/extract | 1 per page | | POST /api/v1/extract/preview | free, no API key | ### 7. Document format conversion Conversion between document formats, where every pair offered was measured rather than advertised. | Endpoint | Credits | |---|---| | POST /api/v1/convert | 1 per document | | POST /api/v1/convert/free | free, no API key | ### 8. PDF tables to a spreadsheet Tables out of a PDF as CSV, XLSX or JSON, with no template to configure. Charged per table-bearing page, and the detector says which pages those are before anything is billed. | Endpoint | Credits | |---|---| | POST /api/v1/tables | 3 per table-bearing page | | POST /api/v1/tables/detect | free, no API key | ### 9. Chat and mail export to an archive A WhatsApp, Gmail or Slack export turned into something readable. **No account and no credits**: $6 for the export, one payment, however long it is, and the file is deleted on delivery. | Endpoint | Credits | |---|---| | POST /api/v1/archive | 2 per export | ### 10. Spreadsheet cleaning Charsets, delimiters, header rows and column types repaired, with a free preview of every cell that would change before anything is accepted. | Endpoint | Credits | |---|---| | POST /api/v1/spreadsheet/clean | 2 plus 1 per 500 rows | | POST /api/v1/spreadsheet/preview | free, no API key | ### 11. YouTube transcripts A video URL in, its transcript out as txt, srt, vtt or json with timings. Captions only: it reads the track YouTube already has and does not transcribe audio, so a video with no captions returns nothing rather than a guess. No video or audio is downloaded on any path. | Endpoint | Credits | |---|---| | POST /api/v1/youtube | 1 per video | | POST /api/v1/youtube/preview | free, no API key | ## Pricing | Pack | Price | Credits | Notes | |---|---|---|---| | Free | $0 | 25 | one-time grant on signup | | Starter | $4.99 | 100 | $0.050 per credit | | Standard | $14.99 | 500 | $0.030 per credit | | Pro | $39.99 | 2,000 | $0.020 per credit | | Business | $79.99 | 5,000 | $0.016 per credit | | Operation | Endpoint | Credits | |---|---|---| | Render markup to PDF | POST /api/v1/render | 1 per document, +1 per 10 pages over 10 | | Render many documents | POST /api/v1/render/batch | 1 per document, failures refunded | | Render a stored template | POST /api/v1/render/from-template | 1 per document | | Merge PDFs | POST /api/v1/pdf/merge | 1 per operation | | Split a PDF | POST /api/v1/pdf/split | 1 per operation, returns a ZIP | | Compress a PDF | POST /api/v1/pdf/compress | 1 per operation | | Rotate pages | POST /api/v1/pdf/rotate | 1 per operation | | Watermark pages | POST /api/v1/pdf/watermark | 1 per operation | | Reorder pages | POST /api/v1/pdf/reorder | 1 per operation | | Extract pages | POST /api/v1/pdf/extract-pages | 1 per operation | | Unlock a PDF | POST /api/v1/pdf/unlock | 1 per operation, password required | | Strip metadata | POST /api/v1/metadata/strip | 1 per operation | | Redact text, patterns or regions | POST /api/v1/redact | 2 per operation | | Inspect metadata | POST /api/v1/metadata/inspect | free, no API key | | Parse a document to markdown | POST /api/v1/parse | 1 per 10 text pages, 1 per OCR page | | Parse many documents | POST /api/v1/parse/batch | same rates, failures refunded | | Convert a document | POST /api/v1/convert | 1 per document | | Convert one small document | POST /api/v1/convert/free | free, no API key | | Extract tables from a PDF | POST /api/v1/tables | 3 per table-bearing page | | Find the tables and the price first | POST /api/v1/tables/detect | free, no API key | | Capture a URL as evidence | POST /api/v1/capture | 1, or 5 retained with a timestamp and manifest | | Verify a capture | GET /api/v1/capture/{id}/verify | free, no API key | | Capture a URL repeatedly | POST /api/v1/capture/schedule | priced per capture | | Read a web page | POST /api/v1/extract | 1 per page | | Read one page, truncated | POST /api/v1/extract/preview | free, no API key | | Clean a spreadsheet | POST /api/v1/spreadsheet/clean | 2 plus 1 per 500 rows | | Preview what cleaning would change | POST /api/v1/spreadsheet/preview | free, no API key | | Turn a chat or mail export into an archive | POST /api/v1/archive | 2 per export | | Get a YouTube transcript | POST /api/v1/youtube | 1 per video | | Get a transcript, truncated | POST /api/v1/youtube/preview | free, no API key | | Store, list, update, delete templates | /api/v1/templates | free | New accounts receive 25 credits on signup. ## Authentication Send `X-API-Key: dk_live_...` on every request. Keys are created in the dashboard, shown once, and stored only as a hash — a lost key is replaced, never recovered. Up to 3 keys per account, so a workload can be isolated and revoked on its own. Rate limits are **per key, not per account**, so one runaway script cannot starve production traffic. ## Endpoints | Endpoint | What | Auth | |---|---|---| | `GET /` | Dashboard Elsewhere | none | | `GET /api/v1/account` | The signed-in account and its balance | API key | | `GET /api/v1/account/packs` | Credit packs and where to buy them | API key | | `GET /api/v1/account/usage` | Recent jobs and what each one cost | API key | | `POST /api/v1/archive` | Turn a chat or mail export into a readable archive | API key | | `POST /api/v1/archive/job` | Upload an export and get a payment link. No API key, no account. | none | | `GET /api/v1/archive/job/{job_id}` | How a per-job archive is getting on. No API key. | none | | `GET /api/v1/archive/job/{job_id}/download` | The finished archive. No API key. | none | | `GET /api/v1/auth/config` | Public sign-in configuration | none | | `POST /api/v1/auth/email/start` | Email a 6-digit sign-in code | none | | `POST /api/v1/auth/email/verify` | Exchange a sign-in code for a session | none | | `POST /api/v1/capture` | Capture a URL as evidence | API key | | `GET /api/v1/capture` | List this account's captures | API key | | `POST /api/v1/capture/job` | Record a URL and get a payment link. No API key, no account. | none | | `GET /api/v1/capture/job/{job_id}` | How a per-job capture is getting on. No API key. | none | | `GET /api/v1/capture/schedule` | List this account's capture schedules | API key | | `POST /api/v1/capture/schedule` | Capture a URL repeatedly | API key | | `PATCH /api/v1/capture/schedule/{schedule_id}` | Pause, resume or re-time a schedule | API key | | `DELETE /api/v1/capture/schedule/{schedule_id}` | Delete a schedule. Its captures are kept. | API key | | `DELETE /api/v1/capture/{capture_id}` | Delete a capture and its stored files. Yours only. | API key | | `GET /api/v1/capture/{capture_id}/artefact/{name}` | Download one stored artefact. Public, no API key. | none | | `GET /api/v1/capture/{capture_id}/verify` | Check a capture's hashes. Public, no API key. | none | | `POST /api/v1/convert` | Convert a document from one format to another | API key | | `GET /api/v1/convert/formats` | Every conversion this API can actually do. Free, no API key. | none | | `POST /api/v1/convert/free` | Convert one small document. Free, no API key. | none | | `POST /api/v1/extract` | Read a web page as clean markdown, text, HTML, PDF or PNG | API key | | `POST /api/v1/extract/preview` | Read one page as markdown. Free, no API key, truncated. | none | | `POST /api/v1/extract/preview/pdf` | The page as a PDF, first 3 pages. Free, no API key. | none | | `GET /api/v1/keys` | List Keys | API key | | `POST /api/v1/keys` | Create Key | API key | | `DELETE /api/v1/keys/{key_id}` | Revoke Key | API key | | `POST /api/v1/metadata/inspect` | Show what a file reveals about you. Free, no API key. | none | | `POST /api/v1/metadata/strip` | Remove metadata from a PDF, JPEG or PNG | API key | | `GET /api/v1/operations` | Every operation a signed-in customer can run, and what it costs | none | | `POST /api/v1/parse` | Parse a document to markdown | API key | | `POST /api/v1/parse/batch` | Parse many documents, streaming results | API key | | `POST /api/v1/pdf/free/{op}` | Compress or unlock one small PDF. Free, no API key. | none | | `POST /api/v1/pdf/{op}` | Run a PDF operation | API key | | `POST /api/v1/pdf/{op}/batch` | Run a PDF operation over many files, streaming results | API key | | `POST /api/v1/redact` | Remove text from a PDF so it cannot be recovered | API key | | `POST /api/v1/render` | Render markup to PDF | API key | | `POST /api/v1/render/batch` | Render many documents, streaming results as Server-Sent Events | API key | | `POST /api/v1/render/from-template` | Render a stored template with data | API key | | `GET /api/v1/results/{key}` | Fetch a result by signed URL | none | | `POST /api/v1/spreadsheet/clean` | Clean a messy spreadsheet: headers, types, merged cells, audit log | API key | | `POST /api/v1/spreadsheet/preview` | What would change, and what it would cost. Free, no API key. | none | | `POST /api/v1/stripe/webhook` | Stripe webhook. Signature-verified; the only path that adds credits. | none | | `POST /api/v1/tables` | Extract tables from a PDF as CSV, XLSX or JSON | API key | | `POST /api/v1/tables/detect` | Which pages have tables, and what it would cost. Free, no API key. | none | | `GET /api/v1/templates` | List this account's templates | API key | | `POST /api/v1/templates` | Store a reusable template | API key | | `GET /api/v1/templates/{template_id}` | Fetch one template | API key | | `PATCH /api/v1/templates/{template_id}` | Update a template | API key | | `DELETE /api/v1/templates/{template_id}` | Delete a template | API key | | `POST /api/v1/youtube` | Get a YouTube video's transcript as txt, srt, vtt or json | API key | | `POST /api/v1/youtube/preview` | Get a transcript. Free, no API key, truncated. | none | | `GET /facts` | Canonical statement of what this product does and does not do | none | | `GET /health` | Health | none | | `GET /health/ready` | Ready | none | | `GET /llms-full.txt` | Full description of the product for AI answer engines | none | | `GET /llms.txt` | Short description of the product for AI answer engines | none | | `GET /mcp` | MCP endpoint. GET is for server-initiated streams, which this server has none of. | none | | `POST /mcp` | MCP endpoint. JSON-RPC 2.0 over HTTP; tools/call needs an API key. | none | | `GET /postman/collection.json` | Postman collection (v2.1.0) for every endpoint | none | ## Batch `POST /api/v1/render/batch` streams Server-Sent Events: one `metadata` event, one `item` event per document as it finishes, and one `done` summary. Items complete out of order, so each `item` event carries its `index`. Failed items are refunded individually — one bad file in a folder of two hundred costs nothing. ## Templates Store markup once, then send data instead of the whole document on every call. Placeholders are `[[ key ]]`, or `{{ key }}` if you prefer — they mean the same thing, but Postman, Insomnia and most CI templating claim `{{ }}` for themselves and substitute it before the request is sent, so square brackets are the safe spelling. Values are escaped for the target format, so data cannot restructure the document it fills in. A missing key is a 422, never a blank — a document that looks finished and is wrong is worse than an error. Templates are free and retained indefinitely. ## Errors Every error has the same shape. **Branch on `code`, never on the HTTP status or the message.** ```json {"error": {"code": "insufficient_credits", "message": "..."}} ``` `missing_api_key` · `invalid_api_key` · `invalid_input` · `insufficient_credits` · `unsupported_format` · `too_large` · `too_many_pages` · `render_failed` · `rate_limited` · `not_found` · `internal_error` ## Limits | Limit | Value | |---|---| | Max upload | 100 MB | | Max pages per document | 500 | | Max items per batch | 200 | | Request timeout | 30 s | | Rate limit, single requests | 60 per minute per key | | Rate limit, batch requests | 10 per minute per key | | Concurrent requests per key | 5 single, 2 batch | | Max API keys per account | 3 | ## Machine-readable - OpenAPI 3.1: https://api.docufinery.com/openapi.json - Postman collection: https://api.docufinery.com/postman/collection.json - Facts, with Product and FAQPage structured data: https://api.docufinery.com/facts