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
curl -X POST https://api.txtfetch.com/v1/extract \
  -H "Authorization: Bearer $TXTFETCH_KEY" \
  -F file=@resume.docx
Python
import 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"])
JavaScript
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);
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("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 →

See the pricing →