> Source: https://txtfetch.com/docs > Plain-text twin — every page on txtfetch.com has one. https://txtfetch.com/text --- # The whole API fits on this page. One endpoint, two ways to call it, one response shape. If you can curl, you've already integrated. Prefer to see it first? [Try the playground →](https://txtfetch.com/playground) ## Authenticate Every request carries your API key in the `Authorization` header. [Create a key in your dashboard](https://app.txtfetch.com/signup). ``` export TXTFETCH_KEY="tf_live_..." ``` A missing key returns `401`. An invalid or revoked key returns `403`. Both come back as API Gateway's platform `{"message": "…"}` body, not the typed error shape below. See [the error reference](https://txtfetch.com/docs/errors) for the full auth-failure semantics. ## Extract a file POST the bytes as multipart form data. Any of the [supported formats](https://txtfetch.com/formats) works. 615 of the 1,683 Tika detects have a real parser, [checked against the exact build we run](https://txtfetch.com/formats/coverage). txtfetch reads the real type from the bytes, not the extension. curl ```curl curl -X POST https://api.txtfetch.com/v1/extract \ -H "Authorization: Bearer $TXTFETCH_KEY" \ -F file=@quarterly-report.pdf ``` Python ```python import os import requests with open("quarterly-report.pdf", "rb") as f: r = requests.post( "https://api.txtfetch.com/v1/extract", headers={"Authorization": f"Bearer {os.environ['TXTFETCH_KEY']}"}, files={"file": f}, ) print(r.json()["extracted_text"]) ``` JavaScript ```javascript import { readFile } from "node:fs/promises"; const file = new Blob([await readFile("quarterly-report.pdf")]); const form = new FormData(); form.append("file", file, "quarterly-report.pdf"); const res = await fetch("https://api.txtfetch.com/v1/extract", { method: "POST", headers: { Authorization: `Bearer ${process.env.TXTFETCH_KEY}` }, body: form, }); const { extracted_text } = await res.json(); console.log(extracted_text); ``` Go ```go package main import ( "bytes" "encoding/json" "fmt" "io" "mime/multipart" "net/http" "os" ) type extractResponse struct { Status string `json:"status"` ExtractedText string `json:"extracted_text"` } func main() { f, err := os.Open("quarterly-report.pdf") if err != nil { panic(err) } defer f.Close() var body bytes.Buffer writer := multipart.NewWriter(&body) part, err := writer.CreateFormFile("file", "quarterly-report.pdf") if err != nil { panic(err) } if _, err := io.Copy(part, f); err != nil { panic(err) } writer.Close() req, err := http.NewRequest("POST", "https://api.txtfetch.com/v1/extract", &body) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("TXTFETCH_KEY")) req.Header.Set("Content-Type", writer.FormDataContentType()) 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) } ``` ## Extract from a URL Or skip the download: pass a `url` parameter and txtfetch fetches the document server-side. curl ```curl curl -X POST "https://api.txtfetch.com/v1/extract?url=https://example.com/whitepaper.docx" \ -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/whitepaper.docx"}, ) print(r.json()["extracted_text"]) ``` JavaScript ```javascript const endpoint = new URL("https://api.txtfetch.com/v1/extract"); endpoint.searchParams.set("url", "https://example.com/whitepaper.docx"); 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/whitepaper.docx") 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) } ``` ## Response Success is always the same shape. Scanned documents and images go through OCR automatically. It's the same request and the same response. ``` { "status": "success", "extracted_text": "Q3 revenue grew 34% year over year, driven by...", "metadata": { "content_type": "application/pdf", "bytes": 482913, "chars": 812, "ocr": false } } ``` ## Response formats Need structure instead of flat text? Pass `?format=markdown` for GFM output, tables included, or `?format=json` for a typed element tree. The endpoint, auth, and error shape stay the same. `format` defaults to `text` (the shape above) when omitted. ``` curl -s -X POST "https://api.txtfetch.com/v1/extract?format=markdown" \ -H "Authorization: Bearer $TXTFETCH_KEY" \ -F file=@quarterly-report.pdf ``` ``` { "status": "success", "markdown": "# Quarterly Report\n\n...\n\n| Region | Revenue |\n| --- | --- |\n| EMEA | 34% |\n", "metadata": { "content_type": "application/pdf", "bytes": 482913, "chars": 812, "format": "markdown", "tier": "standard", "pages": 4, "vlm": false } } ``` ``` curl -s -X POST "https://api.txtfetch.com/v1/extract?format=json" \ -H "Authorization: Bearer $TXTFETCH_KEY" \ -F file=@quarterly-report.pdf ``` ``` { "status": "success", "elements": [ { "type": "heading", "text": "Quarterly Report", "level": 1, "page": 1, "offset": 0, "bbox": null }, { "type": "table", "text": "Region\tRevenue\nEMEA\t34%", "markdown": "| Region | Revenue |\n| --- | --- |\n| EMEA | 34% |", "html": "