https://txtfetch.com/docs/leaving/
Leaving txtfetch
txtfetch is a runtime dependency. If the API is down, your pipeline stops. Here is exactly what that means, and exactly what it costs to swap out.
The whole API surface
A small surface is easy to leave. txtfetch has two endpoints, not a platform.
| Endpoint | What it does |
|---|---|
POST /v1/extract | Submit a document — a file upload or a ?url= to fetch server-side — and extract its text. See the reference → |
GET /v1/extract/{job_id} | Poll an async job for its result, when a request was too large or too slow for the sync path. See the reference → |
The default call returns six fields: status, extracted_text, metadata.content_type, metadata.bytes, metadata.chars, and metadata.ocr. See the full shape on /docs.
?format= changes one key, never the envelope. Every finished extraction returns status, one payload key, and metadata. Pin ?format=json and elements replaces extracted_text. Your adapter reads one key, so it is the one line you re-point.
| Mode | Body | When you get it |
|---|---|---|
format=text (the default) | status, extracted_text, metadata | You send no ?format= at all. One flat string, and the four metadata keys above. See the default response shape → |
format=markdown | status, markdown, metadata | You asked for GFM headings, lists, and tables instead of a flat string. Compare all three output shapes → |
format=json | status, elements, metadata | You asked for typed elements. The elements array replaces extracted_text, so read that key instead. See the element shapes → |
| An async job, not finished yet | status, job_id | Your request was routed to the async path. Poll the job id until the body above comes back. See the async job lifecycle → |
That is the whole contract. 3 of those 4 bodies are declared in /openapi.json. Generate a client against that spec, or read it before you commit to anything.
Nothing to export, because nothing is stored
A data-export tool exists to hand back what a vendor kept. txtfetch does not keep your documents, so there is no export to build.
See the full data-handling posture →
The swap is a one-line change
Every caller in your codebase already talks to one function, not to requests.post directly. Wrap the call once, and leaving is a matter of pointing that wrapper somewhere else.
def extract_txtfetch(path):
"""Default format=text, so the payload key is extracted_text.
Pin ?format=json and you read elements instead."""
import requests
r = requests.post(
"https://api.txtfetch.com/v1/extract",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": open(path, "rb")},
)
return r.json()["extracted_text"]
def extract_self_hosted(path):
from tika import parser
return parser.from_file(path)["content"]
# Both return a plain string, so this line is the whole swap:
extract = extract_txtfetch # or extract_self_hosted
The call itself is an afternoon. The next section is the honest cost: not the code, but the operations you take back.
Where to go instead, and what it costs you
/compare/self-hosted-tika argues that running the stack yourself is expensive, and that is still true here. Swapping the call is cheap. What is expensive is re-owning the work this API currently does for you.
| Replacement | What you take back |
|---|---|
| Run Apache Tika yourself | Every operational choice this API makes for you today: the JDK trim, the Tesseract build for your own runtime, memory and timeout limits, and the 100 MB size ceiling you'd set again from scratch. |
| Switch to an open-source parser | Model-weight downloads, your own OCR engine and its language packs, and a GPU decision for your batch size — the work five different parsers each hand you back in their own way. |
| Move to another vendor | A new billing unit to re-derive your cost against, and a fresh capability table to re-check line by line before you trust it with production traffic. |
Six of those jobs, priced with the same numbers this site publishes:
- The OCR decision. Which engine, which trained-data set, and when to trigger it. txtfetch runs Tesseract 5.5.2 automatically. A PDF page is read when it has 10 typed characters or fewer. A picture file is always read. See the reference →
- The async threshold. Routing a request above 8 MB to a queue instead of the request/response cycle, plus the polling or webhook delivery on the other end. See the async job lifecycle →
- The file-size ceiling. Deciding, and enforcing, how large an input your pipeline accepts before it refuses the request. txtfetch's own ceiling is 100 MB. See every limit in one table →
- Format detection. Identifying what a file actually is before you route it to a parser, instead of trusting its extension or a client-supplied content type.
- The archive guard. Refusing a zip file before it inflates past a safe size or entry count. txtfetch caps entries at 10,000 and refuses anything compressed past 200:1. See every archive guard number →
- Idempotency. Replaying a repeated request instead of re-running it, and rejecting a reused key against a different request body. See the Idempotency-Key contract →
Frequently asked questions
- What happens to my pipeline if txtfetch shuts down?
- Your pipeline stops working, the same as any runtime API dependency. There is no local fallback, and none is promised. The call itself is small: point your adapter at another parser or vendor, and the swap is an afternoon, not a migration project. The cost is the operations you take back, not the code change.
- Do you keep copies of my documents?
- No. Document bytes are held in memory for the extraction, then discarded. An async job's result and an Idempotency-Key replay are cached for one day, then that cache expires too. There is no document store to export from at any point.
- Am I locked into a contract?
- No. Developer and Scale are billed monthly through Stripe, and you can upgrade, downgrade, or cancel anytime from your dashboard. Hobby is free with no card required. Nothing here is an annual commitment.
- Can you export my data?
- There is nothing to export. txtfetch keeps request metadata for metering — timestamps, sizes, status. It never keeps a copy of your document or its extracted text, past the short-lived job and idempotency cache.
Watch it run, then take a key.
The playground replays a real recorded response for every sample document.
Open the playground →