Web and domain tooling

PDF Text Extractor for LLMs: text per page from PDF URLs

Plain text extraction from PDF files by URL, up to 200 files per run: one row per page (or one per file) with the text, page count, title, author, dates, producer and file size, plus whether the page has a text layer at all. Pay per page delivered.

$1.00per 1,000 · Page extracted

One page of text delivered (or one file when pages are merged). Files that cannot be fetched or parsed are never charged.

Call it from your code

curl
ACTOR=steadydata~pdf-text-extractor
URL="https://api.apify.com/v2/acts/$ACTOR/run-sync-get-dataset-items"

curl -X POST "$URL?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://arxiv.org/pdf/1706.03762"], "mergePages": false, "maxPagesPerFile": 200}'
python
import os, requests

ACTOR = "steadydata~pdf-text-extractor"
URL = f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items"

rows = requests.post(
    URL,
    params={"token": os.environ["APIFY_TOKEN"]},
    json={'urls': ['https://arxiv.org/pdf/1706.03762'], 'mergePages': False, 'maxPagesPerFile': 200},
    timeout=900,
).json()

# every row carries a status; failures are records, not exceptions
ok = [r for r in rows if r.get("status") == "ok"]
print(len(ok), "rows delivered")
javascript
const ACTOR = "steadydata~pdf-text-extractor";
const url =
  `https://api.apify.com/v2/acts/${ACTOR}/run-sync-get-dataset-items` +
  `?token=${process.env.APIFY_TOKEN}`;

const rows = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({"urls": ["https://arxiv.org/pdf/1706.03762"], "mergePages": false, "maxPagesPerFile": 200}),
}).then((r) => r.json());

// one object per delivered row, same shape every time
console.log(rows.filter((r) => r.status === "ok").length, "rows");

Use it in an agent

Point an MCP client at Apify's hosted server with this dataset in the tools list, or run our own server locally.

mcp url
https://mcp.apify.com?tools=steadydata/pdf-text-extractor

# the tool arrives in your agent as steadydata--pdf-text-extractor

Input

FieldTypeNameWhat it does
urls
required
array of stringPDF URLsOne URL per row, up to 200. Direct links to PDF files.
mergePagesbooleanOne row per file instead of per pageOff: one row per page. On: one row per file with all pages joined; that row counts as one delivered page.
maxPagesPerFileintegerMax pages per fileCost ceiling per file, from the first page.

What you get back

output schema, one object per delivered row
{
  "url": string | null,
  "fileName": string | null,
  "page": integer | null,
  "pageCount": integer | null,
  "text": string | null,
  "characters": integer | null,
  "hasTextLayer": boolean | null,
  "title": string | null,
  "author": string | null,
  "subject": string | null,
  "createdAt": string | null,
  "modifiedAt": string | null,
  "producer": string | null,
  "fileBytes": integer | null,
  "encrypted": boolean | null,
  "status": string | null,
  "input": string | null,
  "errorCode": string | null,
  "error": string | null
}
FieldTypeWhen it is filled
urlstring, null
fileNamestring, null
pageinteger, null
pageCountinteger, null
textstring, null
charactersinteger, null
hasTextLayerboolean, null
titlestring, null
authorstring, null
subjectstring, null
createdAtstring, null
modifiedAtstring, null
producerstring, null
fileBytesinteger, null
encryptedboolean, null
statusstring, nullEither 'ok' or 'error'. An error row carries errorCode and error, and leaves the data fields empty; it is never charged.
inputstring, nullThe input this row was built from, so a row can always be traced back.
errorCodestring, nullFilled on an error row only; a delivered row leaves it empty.
errorstring, nullFilled on an error row only; a delivered row leaves it empty.

Related datasets

Already using this one? Ratings are the first thing other buyers look at, and this dataset has none yet. If it does a job for you, a rating on its Apify page is the one thing that helps. It takes a minute and it is the only thing we ask for.

Open the Apify page