https://txtfetch.com/solutions/invoice-and-receipt-processing/
Turn invoices and receipts into text your AP tools can use.
Inbound invoices arrive as PDFs, phone photos, scans, spreadsheets, and email attachments. txtfetch turns each one into text and table rows for your own rules or an LLM to parse.
the-problem
Accounts payable teams receive invoices in every shape. A vendor emails a PDF, a contractor texts a photo, a supplier uploads a scan to a portal. Each format needs its own reader before any approval logic can run. Teams that only handle PDFs miss the photos and scans, and those invoices sit in a manual queue.
how-txtfetch-solves-it
txtfetch reads the invoice, whatever the format, and returns the text and the table rows. It does not return a typed total field or a typed vendor field. Pair it with your own rules or an LLM to pull those values out. Pass format=markdown on the same request to keep the line-item table intact for that step.
- OCR runs automatically on photographed and scanned invoices, with no separate vision service.
- format=markdown keeps the line-item table intact for your parser or LLM prompt.
- One endpoint reads a vendor's PDF, a phone photo of a receipt, a spreadsheet, and an email attachment.
- Async job and webhook mode keeps large batch runs from blocking approval queues.
- Idempotency-Key support stops a retried upload from double-processing an invoice.
- The response includes the text and the table rows, ready for your own totals logic.
curl -X POST https://api.txtfetch.com/v1/extract \
-H "Authorization: Bearer $TXTFETCH_KEY" \
-F file=@invoice.pdfimport os
import requests
with open("invoice.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"])import { readFile } from "node:fs/promises";
const file = new Blob([await readFile("invoice.pdf")]);
const form = new FormData();
form.append("file", file, "invoice.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);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("invoice.pdf")
if err != nil {
panic(err)
}
defer f.Close()
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("file", "invoice.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)
}{
"status": "success",
"extracted_text": "..."
}faq
- Does txtfetch return a total or vendor field from an invoice?
- No. It returns the invoice as text and table rows. Pull a typed total or vendor field with your own rules or an LLM.
- Can txtfetch read a photographed invoice from a phone?
- Yes. OCR runs automatically on the photo, and the response has the same shape as a digital-native PDF.
- How do I keep the line-item table readable for my parser?
- Add format=markdown to the request. The table rows stay intact instead of flattening into one block of text.
related-reading
Start on the free plan.
Run your own documents through it before you commit. The Hobby plan needs no card.
Get started →