> Source: https://txtfetch.com/integrations/zapier > Plain-text twin — every page on txtfetch.com has one. https://txtfetch.com/text --- # Extract text in a Zap, no txtfetch app required. There is no txtfetch app in the Zapier directory. Webhooks by Zapier's Custom Request action calls the same API directly, and a link works better than a file step ever would. the-problem A Zap that needs text out of an incoming document usually starts from a Google Drive file, a Gmail attachment, or a form upload. Zapier's steps pass those around as file objects. Forwarding one to a Custom Request action as binary data is fiddly and easy to get wrong. Zaps also run on a fixed step timeout. A document that takes a while to OCR can fail the step before it ever gets a result back. how-to-wire-it-up txtfetch has no Zapier integration listed in the app directory. Webhooks by Zapier's Custom Request action reaches the same REST endpoint a curl command would, with no app to install first. Most upstream steps already expose a shareable link for the file — a Google Drive share link, a Gmail attachment URL. Pass that as the url query parameter, instead of trying to forward the file's bytes. For a document that's large or slow, add async and webhook\_url to the same request. Then let a second Zap start from a Catch Hook trigger when the result is ready. - Pass ?url= with a file's existing share link, so the Custom Request action never handles binary file data. - Automatic OCR covers scanned PDFs and photographed forms, with no separate OCR app needed in the Zap. - Async mode returns a job\_id immediately, so a slow extraction never times out the Custom Request step. - A Catch Hook trigger on a second Zap picks up the webhook\_url callback and continues the automation from there. - Idempotency-Key support keeps a Zapier auto-replay from re-running and re-billing the same extraction. pass-a-link-not-a-file curl ```curl curl -X POST "https://api.txtfetch.com/v1/extract?url=https://example.com/report.pdf" \ -H "Authorization: Bearer $TXTFETCH_KEY" ``` Python ```python import os import requests r = requests.post( "https://api.txtfetch.com/v1/extract", headers={"Authorization": f"Bearer {os.environ['TXTFETCH_KEY']}"}, params={"url": "https://example.com/report.pdf"}, ) print(r.json()["extracted_text"]) ``` JavaScript ```javascript const endpoint = new URL("https://api.txtfetch.com/v1/extract"); endpoint.searchParams.set("url", "https://example.com/report.pdf"); const res = await fetch(endpoint, { method: "POST", headers: { Authorization: `Bearer ${process.env.TXTFETCH_KEY}` }, }); const { extracted_text } = await res.json(); console.log(extracted_text); ``` Go ```go package main import ( "encoding/json" "fmt" "net/http" "net/url" "os" ) type extractResponse struct { Status string `json:"status"` ExtractedText string `json:"extracted_text"` } func main() { endpoint, err := url.Parse("https://api.txtfetch.com/v1/extract") if err != nil { panic(err) } q := endpoint.Query() q.Set("url", "https://example.com/report.pdf") endpoint.RawQuery = q.Encode() req, err := http.NewRequest("POST", endpoint.String(), nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("TXTFETCH_KEY")) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() var result extractResponse if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { panic(err) } fmt.Println(result.ExtractedText) } ``` ``` { "status": "success", "extracted_text": "..." } ``` large-or-slow-documents `POST /v1/extract` returns `202` with a `job_id` whenever the document is large or slow to process, or whenever `async=true` is set. Poll `GET /v1/extract/{job_id}` for the result, or set `webhook_url` and have txtfetch push it instead. No single request on this page is safe to assume will always finish synchronously. Submit (async) ```submit curl -X POST "https://api.txtfetch.com/v1/extract?url=https://example.com/report.pdf&async=true" \ -H "Authorization: Bearer $TXTFETCH_KEY" # {"status": "processing", "job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"} ``` Poll ```poll curl "https://api.txtfetch.com/v1/extract/3fa85f64-5717-4562-b3fc-2c963f66afa6" \ -H "Authorization: Bearer $TXTFETCH_KEY" # {"status": "processing", "job_id": "..."} while running, then the same # {"status": "success", "extracted_text": "...", "metadata": {...}} shape # POST /v1/extract would have returned synchronously. ``` curl ```curl curl -X POST "https://api.txtfetch.com/v1/extract?url=https://example.com/report.pdf" \ -H "Authorization: Bearer $TXTFETCH_KEY" \ --data-urlencode "webhook_url=https://example.com/webhooks/txtfetch" ``` setup-steps 1. Add a Webhooks by Zapier action and choose Custom Request. 2. Set Method to POST. 3. Set URL to https://api.txtfetch.com/v1/extract, then add url as a query string parameter with the document's link. 4. Under Headers, add Authorization with the value Bearer, followed by your API key. 5. For a large document, add async set to true and webhook\_url set to a second Zap's Catch Hook address. 6. Test the action. Zapier shows extracted\_text in the returned data, ready to map into the next step. faq **Is there a txtfetch app in the Zapier directory?**: No. txtfetch has no listed Zapier app or connector. Webhooks by Zapier's Custom Request action reaches the same REST API with no app install needed. **How do I send a file from a Zap without a txtfetch app?**: Use the file's share link from the upstream step — Google Drive, Dropbox, and Gmail attachments all expose one. Pass it as the url query parameter, rather than forwarding the file itself. **Can a Zap wait for a slow OCR job without timing out?**: Yes. Add async=true and webhook_url to the request, and end the first Zap there. Start a second Zap from a Catch Hook trigger when the callback arrives. **How does a Zap tell a failed extraction from a successful one?**: Check the status field in the response. A failed request still returns a typed error.code instead of extracted_text, so a Filter step can catch it before the Zap continues. related-reading - [Batch and large-document ingestion →](https://txtfetch.com/blog/batch-and-large-document-ingestion) - [Parsing Office docs into clean text →](https://txtfetch.com/blog/parse-office-docs-docx-pptx-xlsx-for-llms) - [Async jobs & webhooks →](https://txtfetch.com/docs/async) - [Error reference →](https://txtfetch.com/docs/errors) - [Get an API key →](https://app.txtfetch.com/signup) other-integrations - [n8n →](https://txtfetch.com/integrations/n8n) - [Make →](https://txtfetch.com/integrations/make) - [Apache Airflow →](https://txtfetch.com/integrations/airflow) - [S3 and Lambda →](https://txtfetch.com/integrations/aws-s3-lambda) ## Add the step to your Zapier flow. One HTTP node with your key does the whole job. [Get an API key →](https://app.txtfetch.com/signup) [See every integration →](https://txtfetch.com/integrations)