A ceramic water mill turning a mixed stream of paper sheets, photo prints, and ledger pages into a single clear channel of plain text slips
All posts

How to extract text from a URL, scanned PDF or image for an LLM pipeline

Use AIVAX Fetch to extract text from URLs, scanned PDFs and images, with per-item errors, processing-unit usage and optional schema-guided JSON.

To extract text from a URL, scanned PDF or image for an LLM pipeline, send its public URL or base64 data URI to AIVAX POST https://inference.aivax.net/api/v1/web/fetch. The endpoint returns extracted text, processing-unit usage and errors per item, plus optional schema-guided JSON. Text extraction is billed in processing units (PUs), with plan-dependent daily allowances; JSON conversion is charged separately.

Keep that result before sending selected passages to a model. It gives your application a source-to-text record, a way to identify failed items, and separate usage figures for reading and structuring the content.

What can Fetch read?

Fetch and OCR accepts a non-empty contents array. Each entry is a URL or a base64 data URI with a MIME type, such as data:application/pdf;base64,... for a PDF or data:image/png;base64,... for a PNG. Use a directly accessible file URL rather than a sharing page that requires a login.

Supported inputs and the text Fetch extracts
SourceFormatsWhat you get
Web pagesHTML, XHTMLReadable page text; dynamic content depends on the rendering path
Plain textTXT, MarkdownDocument text, preserving existing Markdown formatting
PDFsPDFDigital text and OCR text from scanned pages, combined where needed
Images with textPNG, JPEG, WebP, TIFF, BMPRecognized text from screenshots, receipts and scans
Office documentsDOC, DOCX, ODT, RTF, PPT, PPTX, ODPDocument or slide text
SpreadsheetsXLSX, ODS, CSVCell and row content as text
E-booksEPUBPublication text

Extraction does not reproduce the original layout. Tables, charts and poor scans can lose structure or characters. Review consequential names, amounts and quotations against the source before using them in a decision or embedding them in a collection.

How do I get typed JSON from the extracted text?

Add responseSchema when downstream code needs fields instead of paragraphs. The same JSON Schema applies to every item in the request, and successful results retain extractedText alongside extractedObject. The optional instructions property inside the schema is an AIVAX extension, not a standard JSON Schema keyword.

Save this example as extract-receipt.mjs. Run it with Bun, an AIVAX_API_KEY environment variable and a public receipt-image URL as its first argument. It prints the extracted fields, source text and both usage counters; it does not write to a ledger or assume that extracted values are correct.

const source = process.argv[2];
const apiKey = process.env.AIVAX_API_KEY;

if (!source || !apiKey) {
  throw new Error("Set AIVAX_API_KEY and run: bun extract-receipt.mjs <public-receipt-url>");
}

const response = await fetch(
  "https://inference.aivax.net/api/v1/web/fetch",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      contents: [source],
      returnErrors: true,
      responseSchema: {
        type: "object",
        instructions: "Extract only information printed on the receipt. Use null for missing values.",
        properties: {
          merchant: { type: ["string", "null"] },
          total: { type: ["number", "null"] },
          date: { type: ["string", "null"] },
        },
        required: ["merchant", "total", "date"],
      },
    }),
  },
);

if (!response.ok) {
  throw new Error(`Fetch request failed: HTTP ${response.status}`);
}

const item = (await response.json()).data.results[0];

if (item.error) {
  throw new Error(`Item ${item.index} failed: ${item.error}`);
}

console.log(JSON.stringify(item, null, 2));

Omit responseSchema, or set it to null, for text-only extraction: extractedObject is then null and jsonProcessingUnits is 0. Schema-guided JSON is generated from the extracted text, not from a fresh visual reading of the original. Validate the returned structure and verify important fields before making a downstream write.

How should I handle errors in a multi-item request?

Match each result to its source using index, the zero-based position in contents. Check both the HTTP response and each item's error; a successful HTTP request is not proof that every source was read successfully.

returnErrors defaults to true. Reported failures contain an error message, null extracted values and zero PU fields. With returnErrors: false, failed items are omitted. If JSON conversion fails, the API does not return that item as a text-only success. Keep failed source identifiers so you can correct or retry those inputs without resubmitting the whole list.

Also inspect the content itself. A login page, access-denied notice or retrieval-failure message is not useful source text, even if it reaches your application as text. Fetch does not bypass authentication or site restrictions. Submit only accessible content you are authorized to process.

How is Fetch priced?

Text and Markdown extraction use 0 PUs. HTML processing is metered at 10 PUs per second, rounded up to a whole PU; the meter covers the HTML conversion or rendering path used. Document and image extraction report their own per-item PU usage. These figures measure processing, not OCR accuracy or a guaranteed number of pages.

Daily extraction PU allowances vary by plan: the Pro allowance is 10× Free, and the Max allowance is 5× Pro. An extraction that is not covered is billed in full at $0.15 per 1,000 PUs on Free, $0.05 on Pro, or $0.02 on Max; coverage is not split within one extraction. Check Pricing and Plans and limits before estimating a workload.

processingUnits and jsonProcessingUnits have different billing paths. Optional JSON conversion has a variable inference-based PU price and is not covered by the daily extraction allowance. Do not add both counters and apply the OCR rate to the total. Any later LLM analysis is another, separately billed step.

Should I use the API, MCP or a built-in tool?

Use the direct API when your application chooses inputs and needs per-item results, usage counters or schema-guided JSON. The Web Utilities MCP fetch_url tool accepts one to five public URLs and returns aggregated text. Inline base64 data goes through the direct API, not that MCP tool. During AIVAX inference, enable the OpenUrl built-in tool when the model should decide when to read a URL; its callable function is open_url.

For a research workflow, search discovers sources and Fetch reads selected URLs. Keep retrieved text separate from application instructions: a fetched page can contain misleading claims or prompt-like content, and retrieval does not make it authoritative.

For RAG ingestion, convert a PDF to Markdown and split it into chunks with Text Segmentation, then prepare the import. Before scaling that workflow, check PDF ingestion quality before embedding so extraction errors do not become persistent retrieval errors.

Frequently asked questions

Can I OCR a scanned PDF through an API?

Yes. Submit the PDF as a public file URL or a base64 PDF data URI; Fetch uses OCR for scanned content. Test representative pages first, especially faint scans, rotated text and dense tables, rather than assuming every character will be recovered.

Does Fetch run JavaScript on pages?

The Fetch and OCR documentation describes JavaScript and CSS rendering for web pages, but the rendering path can vary by request, and inline HTML is parsed without executing scripts. Do not assume that JavaScript-only content is present: check the extracted text for the content you need.

What is the size limit?

The documented Fetch limit is 10 MB per item. For a base64 data URI, that limit applies to decoded file bytes, not the length of the base64 string.

Fetch or Media Descriptions?

Choose Fetch to extract existing text. Choose Media Descriptions when you need model-guided interpretation of visual or audiovisual content, such as explaining a chart.