Migrate from Mindee to txtfetch

Typed fields, not text. Read this one before you switch anything. Here's what your code looks like before and after.

txtfetch does not return typed fields. Its structured-output capability is not yet shipped. Keep Mindee for field extraction, or move to plain text plus your own parser. This page does not claim parity.

Where you are today

The call below is the v1 InvoiceV4 product API, checked against Mindee's current docs.

Python
import os

from mindee import PathInput
from mindee.v1 import Client, product

client = Client(api_key=os.environ["MINDEE_API_KEY"])
input_doc = PathInput("invoice.pdf")

result = client.parse(product.InvoiceV4, input_doc)
invoice = result.document

Mindee runs two API generations. Mindee does not call V1 deprecated. Its own V1 overview says V1 stays maintained, gets no new features, and has no shut-off date. You cannot open a new V1 account today. New signups use Mindee's V2 model-id extraction API instead.

Checked against Mindee's docs on 2026-09-10, using mindee 5.3.0.

the call that replaces it

One HTTP call. No SDK to install, and no job to poll.

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

drop-in adapter

A short function standing in for result.document.<field>.value (no equivalent, see below). Change one function, not your whole pipeline.

Python
import os

import requests


def extracted_text_only(file_path: str) -> str:
    """Not a drop-in for result.document. There is no typed-field
    equivalent here, only the raw text those fields were pulled from.
    Use this to feed your own parser, not to replace field reads.
    """
    with open(file_path, "rb") as f:
        r = requests.post(
            "https://api.txtfetch.com/v1/extract",
            headers={"Authorization": f"Bearer {os.environ['TXTFETCH_KEY']}"},
            files={"file": f},
        )
    r.raise_for_status()
    return r.json()["extracted_text"]
JavaScript
import { readFile } from "node:fs/promises";

// Not a drop-in for result.document. There is no typed-field equivalent
// here, only the raw text those fields were pulled from.
async function extractedTextOnly(filePath) {
  const file = new Blob([await readFile(filePath)]);
  const form = new FormData();
  form.append("file", file, filePath);

  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();
  return extracted_text;
}

field mapping

Mindee's response fields, mapped to txtfetch's
Mindee fieldtxtfetch equivalentNote
invoice.total_amount.valuenot returnedNo typed fields come back. You would parse the total out of extracted_text yourself.
invoice.supplier_name.valuenot returnedSame gap. This is the field extraction that makes Mindee Mindee.
invoice.line_items (list of typed rows)not returnedNo structured line items. The row text is in extracted_text, unparsed.
field.confidence (per field)not returnedNo confidence score exists, because no field exists to score.

what you lose

  • Every typed field: totals, dates, supplier name, line items, and the rest of the invoice schema.
  • Per-field confidence scores for automating approval thresholds.
  • Prebuilt models for receipts, passports, IDs, and driver's licenses.
  • Custom Document APIs for training a field-extraction model on your own document types.

See the full capability table on txtfetch vs Mindee.

what you gain

  • Hundreds of formats through one endpoint (see /formats/coverage), not a narrow set of invoice-shaped documents.
  • One flat call with no per-document-type model to pick.
  • 500 documents a month on the free Hobby plan, with no card and no trial clock.

The pricing math behind per-document billing lives on why per-page pricing punishes long documents.

Cutover

This is not a cutover. Keep Mindee running for the fields your pipeline reads today. Add txtfetch only where you need the raw text Mindee's fields were extracted from, or where your own parser can read plain text well enough.

frequently asked questions

Can txtfetch replace Mindee outright?
No, not today. Mindee returns typed fields like total_amount and supplier_name. txtfetch returns plain text only. Keep Mindee if your pipeline reads those fields.
When would I add txtfetch alongside Mindee, not instead of it?
Add it when you need raw text a Mindee model doesn't cover. That includes a document type with no prebuilt model, or your own parser that only needs clean input text.
Does txtfetch have a roadmap for typed field extraction?
Structured markdown and element-JSON output already ship. Schema-defined field extraction is on the roadmap, not shipped. This page won't claim it early.

Swap the call. Keep the pipeline.

Point your Mindee code at txtfetch, then diff the output before you cut over.

Get an API key →

See the migration guide →