Where your file goes

/docs/personal-data traces your text after it leaves txtfetch. This page traces the minutes before that, inside txtfetch itself.

One document, hop by hop

Every row below names the file that enforces it. Read the source before you trust the claim.

Every hop a document takes inside txtfetch
HopHeld byRegionHow long
EdgeCloudFront and API GatewayNearest AWS edge locationNot held. Passed straight through.
The extract LambdaThe extract Lambda functionus-west-2 (Oregon)One request. Freed when it ends.
A ?url= fetchThe extract Lambda, on your behalfus-west-2 (Oregon)The length of the fetch. Not stored.
The S3 bufferA private S3 bucketus-west-2 (Oregon)1 day, then the object is gone.
The async resultThe same S3 bucketus-west-2 (Oregon)1 day, the same rule as the buffer.
An idempotency recordThe same S3 bucketus-west-2 (Oregon)1 day, the same rule as the buffer.
A webhookYour own serverWherever you host webhook_urlSet by you. This hop is yours.
LogsCloudWatch Logsus-west-2 (Oregon)14 days, then the log group expires it.
Usage recordsDynamoDBus-west-2 (Oregon)Metadata only, on its own retention schedule.
The premium tierNobody. This hop does not run.None. Not in production.Never reached.
Edge
CloudFront and API Gateway end the TLS connection at the edge. They read request metadata to route the call, and pass your document bytes straight through.
terraform/api-extract/edge.tf, apigateway.tf
The extract Lambda
Your document bytes sit in the function's memory for the length of one request. Tika and Tesseract run in that same process. Nothing is written to disk on this hop.
terraform/api-extract/state.tf:26-27 (the default provider's region), config.js:69: AWS_REGION default
A ?url= fetch
Pass ?url= instead of a file, and txtfetch fetches it for you. The target site sees an AWS address, not your own. A port allowlist, a redirect cap, and an SSRF check all run again on every redirect hop, not just the first one.
api/extract/src/fetch-url.js:33, ssrf.js
The S3 buffer
A large or slow input buffers to S3 under buffer/<job_id>/input, encrypted at rest with AES256. Bucket versioning is switched off on purpose: a kept prior version of your document is exactly the retention this API promises not to have.
terraform/api-extract/jobs.tf:22-27 (encryption), jobs.tf:31-38 (versioning), jobs.tf:46-60 (1-day expiry)
The async result
For an async job, result.json holds your extracted text in the same bucket, under the same one-day rule. This is the one hop where extracted text rests on disk rather than in memory.
api/extract/src/jobs.js:114-142 (resultKey, putResult, getJobStatus)
An idempotency record
Replay a request with the same Idempotency-Key, and txtfetch stores the response it sent back, under the same prefix and the same one-day rule.
api/extract/src/jobs.js:144-166 (idemRecordKey, putIdemRecord, getIdemRecord)
A webhook
Give txtfetch a webhook_url, and it POSTs the finished result there, signed with HMAC so you can verify it came from txtfetch. Past this point, retention is your call, not ours.
api/extract/src/webhook.js (HMAC signature), config.js: WEBHOOK_SIGNING_SECRET
Logs
A request log carries an allowlist of body-free fields: request ID, method, route, mode, content type, size, whether it was async, and a key ID. Your document body and the extracted text never reach the logger. The module has no dependencies, so a CI check can prove that directly.
api/extract/src/redact.js:6-27, terraform/api-extract/lambda.tf:27 and apigateway.tf:79 (14-day retention)
Usage records
A usage counter and a usage record track that a request happened, its size, and its status. Neither holds your document or its extracted text. See the full retention schedule on the limits page.
api/extract/src/config.js: COUNTER_RETENTION_DAYS, USAGE_RECORD_RETENTION_DAYS
The premium tier
?quality=premium is sold as a tier, but VLM_ENABLED defaults to false and no operator has switched the tier on in production. Every premium request downgrades to the standard Tika path instead. This would be the only hop that sends content outside the txtfetch AWS account.
api/extract/src/config.js:132: VLM_ENABLED, vlm.js:21 (ANTHROPIC_BASE_URL), terraform/api-extract/variables.tf:229-233

See the full webhook delivery contract →

See the usage-record retention schedule →

The one hop that would leave the building

?quality=premium is sold as a tier, but it does not run today. VLM_ENABLED defaults to false, and no operator has switched the tier on in production. A premium request downgrades to the standard Tika path instead.

The tier is listed on /pricing. See /docs/limits for its page and byte caps, and /compare/multimodal-llm for what it is for.

What this page does not cover

This page stops at txtfetch's own door. What happens to your extracted text after that, your log, your prompt, your embedding provider, your vector store, is covered on /docs/personal-data. Usage-record retention has its own full schedule on /docs/limits.

Watch it run, then take a key.

The playground replays a real recorded response for every sample document.

Open the playground →

Get an API key →