https://txtfetch.com/solutions/resume-and-cv-parsing/
Turn any résumé format into text your ATS can search.
Candidates upload whatever they have: .docx, .pdf, .doc, .odt, .rtf, and sometimes a design-tool PDF with no text layer. txtfetch turns every one of them into plain text.
the-problem
Applicant tracking systems accept whatever a candidate uploads. Most resumes arrive as .docx or .pdf, but some come as .doc, .odt, or .rtf. A design-tool export sometimes has no text layer at all, just an image of the page. A parser tuned for one format silently drops every candidate who used another.
how-txtfetch-solves-it
txtfetch returns the résumé as plain text, whatever the source format. It does not return a typed name, skill, or date field. Feed that text to your own parser or an LLM to pull structured fields out. A design-tool PDF with no text layer still works, because OCR runs automatically.
- One endpoint reads .docx, .pdf, .doc, .odt, and .rtf.
- OCR runs automatically on a design-tool PDF with no text layer.
- The response is plain text, ready for your own parser or LLM to structure.
- Async job and webhook mode covers bulk résumé imports.
- Idempotency-Key support stops a retried upload from reprocessing the same résumé.
- A batch of mixed .docx, .pdf, and scanned résumés needs no branching logic on your side.
curl -X POST https://api.txtfetch.com/v1/extract \
-H "Authorization: Bearer $TXTFETCH_KEY" \
-F file=@resume.docximport os
import requests
with open("resume.docx", "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("resume.docx")]);
const form = new FormData();
form.append("file", file, "resume.docx");
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("resume.docx")
if err != nil {
panic(err)
}
defer f.Close()
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("file", "resume.docx")
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 extract structured fields like name or skills from a résumé?
- No. It returns the résumé as plain text. Pull structured fields with your own parser or an LLM.
- What happens with a résumé exported from a design tool with no text layer?
- OCR runs automatically, the same as any scanned page, so you still get text back.
- Which resume file formats does txtfetch read?
- docx, pdf, doc, odt, and rtf, all through the same endpoint.
related-reading
Start on the free plan.
Run your own documents through it before you commit. The Hobby plan needs no card.
Get started →