Extract text from anything, one format at a time.
Every format has its own gotchas. Pick yours below for the working curl, the covered extensions, and the answers people actually search for.
Prefer to start from your language instead of the file format? See extract by language for Python, JavaScript, Go, Java, and C#.
PDF & scans
.pdf (digital)Extract text from any PDF, one request.
Multi-column academic papers, dense financial tables, scanned contracts — one endpoint, one response shape, no per-layout tuning.
.pdf
.pdf (scanned)Scanned PDFs, OCR'd without a flag.
No text layer, skewed feeder scans, low-DPI faxes — txtfetch detects the blank pass itself and retries through OCR, same request.
.pdf
Office
.docxEvery Office format, one endpoint.
Word, PowerPoint, Excel, RTF, OpenDocument — the breadth that per-format libraries and screenshot-reading VLMs both struggle to cover in one pipeline.
.docx.doc.pptx.ppt.xlsx.xls.odt.ods.odp.rtf
.pptxSlide text and speaker notes, together.
Most extractors keep one or the other. txtfetch reads slide bodies and speaker notes from the same request.
.pptx.ppt.pptm.potx.odp
.xlsxSpreadsheets, resolved not raw.
Cell values are indices into a shared string table, formulas store their formula, not their answer — Tika resolves both before you ever see the response.
.xlsx.xls.xlsm.csv.ods
.docThe 97-2003 binary formats, read properly.
OLE2 Compound File Binary Format isn't a smaller version of OOXML — it's a different filesystem-in-a-file, and .doc text isn't stored in reading order.
.doc.xls.ppt.pub.wpd
.rtfRTF, parsed — not regex-stripped.
\uN? Unicode escapes are followed by an ANSI fallback character on purpose — strip backslashes with a regex and you duplicate every non-ASCII character in the document.
.rtf
.emlEmail, headers to attachments, one call.
From/To/Subject headers, the message body, and attached documents — extracted together, not as separate steps you have to orchestrate.
.eml.msg.mbox
.msgOutlook .msg isn't email, structurally.
MAPI property streams inside an OLE2 container, nested .msg-in-.msg attachments, whole mailbox databases — none of it looks like an .eml file.
.msg.eml.mbox.pst.ost
Web & data
.htmlAny web page, fetched and stripped to text.
Pass a URL, not a file — txtfetch fetches the page server-side and hands back the article, not the nav bar, ads, and cookie banners around it.
.html.htm.xhtml
.csvCSV, decoded from the bytes.
Comma, semicolon, tab or pipe; UTF-8, Windows-1252, or UTF-16 with a BOM — txtfetch settles the encoding question from the file itself and hands back the rows exactly as written.
.csv.tsv.psv.txt
.xmlMarkup stripped, order preserved.
DITA, DocBook, JATS, XBRL filings — the content is real prose buried in tags, entities, and attributes, in document order, not alphabetical or arbitrary order.
.xml.json.yaml.html.xhtml.svg
Images & OCR
.pngOCR that's just another curl request.
Scanned receipts, faxed contracts, photographed whiteboards — Tesseract OCR runs automatically, no separate OCR pipeline to stand up.
.png.jpg.jpeg.tiff.tif.bmp.gif
.tiffEvery page of the TIFF, not just the first.
A multi-page fax TIFF is a chain of image directories, not one picture. Read the file the way most image loaders do and you silently lose every page after the first.
.tiff.tif.jpg.png.bmp.webp.gif
Books & archives
.epubEbooks in, chapter text out.
EPUB's zipped-XHTML internals are exactly the kind of format archaeology txtfetch exists to hide from you.
.epub
.zipOne ZIP, every file's text back.
Skip the unzip-then-loop script. Point txtfetch at an archive and get every contained document's text back from one request.
.zip
Stop parsing. Start shipping.
Create an account and get an API key in minutes — the free Hobby plan needs no card.
Get started →