docsmith / v0.2
Documents in. Markdown, text, pixels and clean images out.
A small HTTP API for the boring half of document work: turn a PDF into Markdown that a retrieval pipeline can actually chunk, pull the raw text, render pages to PNG or JPEG, and convert or shrink images. No models, no queues, no per-page surprises. One request, one answer.
Endpoints
| endpoint | what it does |
|---|---|
| POST /v1/pdf/markdown | Markdown with heading levels, rejoined paragraphs, normalised lists and page boundaries. Returns the heading outline as JSON too. |
| POST /v1/pdf/text | Extract text, optionally layout-preserving and page-ranged. |
| POST /v1/pdf/info | Page count, page size, encryption, title. |
| POST /v1/pdf/images | Render pages to PNG or JPEG at 72-300 dpi. One page returns an image, several return a zip. |
| POST /v1/image/convert | JPEG, PNG, WebP or GIF, with resize, quality and metadata stripping. |
| GET /healthz | Liveness plus which engines are present. |
| GET /openapi.json | OpenAPI 3.0 description, importable into any client or marketplace. |
Call it
curl -sS -X POST "$BASE/v1/pdf/markdown" \ -H "X-API-Key: $DOCSMITH_KEY" \ -F "file=@manual.pdf" -F "pages=1-20" | jq -r .markdown curl -sS -X POST "$BASE/v1/pdf/text" \ -H "X-API-Key: $DOCSMITH_KEY" \ -F "file=@contract.pdf" \ -F "pages=1-2" curl -sS -X POST "$BASE/v1/pdf/images" \ -H "X-API-Key: $DOCSMITH_KEY" \ -F "file=@deck.pdf" -F "dpi=150" -F "format=png" -o page.zip curl -sS -X POST "$BASE/v1/image/convert" \ -H "X-API-Key: $DOCSMITH_KEY" \ -F "file=@photo.jpg" -F "format=webp" -F "max_width=1600" -o photo.webp
What "Markdown" means here
Structure is recovered from the layout, not from a language model, so it is the same output every time and it costs the same per page as the raw text. The rules:
- Heading levels come from relative font size and weight, and only sizes at least 8% apart get their own level.
- Paragraphs are rejoined across visual line breaks, including hyphenated and soft-hyphenated words, using the document's own measured line spacing.
- Bullet glyphs become
-, numbered markers are kept as written, and---marks each page boundary. - Standalone page numbers are dropped as furniture; body text beginning with Markdown syntax is escaped so it cannot forge a heading.
- When the layout is ambiguous it stays a plain paragraph, because a false heading splits a chunk in the wrong place and nobody notices.
Pricing
| plan | requests / month | price | notes |
|---|---|---|---|
| Free | 100 | $0 | Same endpoints, 20MB uploads. |
| Starter | 5,000 | $9 | Email support, 99% target. |
| Pro | 50,000 | $39 | Highest render dpi, priority queue. |
Calls that fail validation are not counted.
A successful response carries X-Quota-Remaining and X-Quota-Reset.
What it does not do
- No OCR. Scanned pages come back empty, and pretending otherwise would waste your time.
/v1/pdf/markdownsays so with a422 no_text_layerinstead of returning an empty document. - No table reconstruction and no reflowing of multi-column pages. Cells and columns arrive in reading order as text, which is right for search and wrong for spreadsheets - use the extracted text if you need the grid back.
- No URL fetching. You upload the bytes; the server never makes an outbound request.
- No storage. Files live in a per-request temp directory and are deleted before the reply is written.
- No LLM calls, so latency is a function of page count, not of someone else's queue.