Best Reworkd Alternative for Multi-Format File Ingestion

EnConvert is a Reworkd alternative for file ingestion that turns PDFs, DOCX, and web pages into clean Markdown and chunks through one API and one schema

Get API key

A developer building a RAG pipeline or AI agent needs a single ingestion layer that handles web pages, PDFs, DOCX files, and other document types and returns consistent LLM-ready output across all of them. Reworkd was an AI web scraping platform built for structured data extraction from websites at scale, using agents that generated self-healing scrapers, and it announced the sunset of its product on 6 February 2025. Even when it was running, its scope was web data, so ingesting a PDF or converting a DOCX alongside web content meant a second integration. EnConvert is a REST API and MCP server with dedicated endpoints for web scraping, file ingestion, document conversion, and summarisation, all returning consistent LLM-ready output from one API, so you get one ingestion layer for web pages and files with no second integration needed.

Example

python
import json
import os
import time

import requests

HEADERS = {"X-API-Key": os.environ["ENCONVERT_API_KEY"]}
PAGE_URL = os.environ["PAGE_URL"]  # the web page URL to ingest


def load_chunks(job_id: str, max_wait_seconds: int = 600) -> list[dict]:
    """Wait for an ingest job (web or file) and return its JSONL chunks."""
    deadline = time.monotonic() + max_wait_seconds
    while time.monotonic() < deadline:
        poll = requests.get(
            f"https://api.enconvert.com/v2/ingest/{job_id}",
            headers=HEADERS,
            timeout=60,
        )
        poll.raise_for_status()
        job = poll.json()
        if job["status"] == "completed":
            break
        if job["status"] in ("failed", "canceled"):
            raise RuntimeError(
                job.get("error_message") or f"Ingest job {job_id} was {job['status']}"
            )
        time.sleep(2)
    else:
        raise TimeoutError(f"Ingest job {job_id} did not finish in {max_wait_seconds}s")

    # output_url is a signed URL (valid 15 minutes). Plain GET, no API key.
    jsonl = requests.get(job["output_url"], timeout=60)
    jsonl.raise_for_status()

    # One chunk per line: {"id", "content", "metadata": {"source_url", "title",
    # "headings_path", "section", "word_count", "chunk_index"}}. Web pages also
    # carry render_quality and deductions in metadata. The file is UTF-8, so split
    # the raw bytes instead of relying on the charset guessed from the headers.
    return [json.loads(line) for line in jsonl.content.splitlines() if line.strip()]


# Step 1: submit a web page (mode "urls") and a PDF; both answer 202 + job_id
page_job = requests.post(
    "https://api.enconvert.com/v2/ingest",
    headers=HEADERS,
    json={"mode": "urls", "urls": [PAGE_URL]},
    timeout=60,
)
page_job.raise_for_status()

with open("/path/to/your/report.pdf", "rb") as f:
    pdf_job = requests.post(
        "https://api.enconvert.com/v2/ingest/files",
        headers=HEADERS,
        files={"files": ("report.pdf", f, "application/pdf")},
        timeout=60,
    )
pdf_job.raise_for_status()

# Step 2: same poll, same JSONL parse, same error handling for both jobs
chunks = load_chunks(page_job.json()["job_id"]) + load_chunks(pdf_job.json()["job_id"])

# metadata.source_url is the page URL for web pages and the filename for uploads
print(f"Loaded {len(chunks)} chunks from the page and the PDF, ready for embedding")

# Next: embed chunk["content"] and store chunk["metadata"] alongside it

# Step 3 (optional): the Reworkd side, only if you still have a Reworkd group.
# reworkd.ai says the product was scheduled to be sunset on February 6, 2025.
# Groups and schemas are set up in its dashboard; the public API reads their
# outputs (GET /v1/outputs/{group_id}) instead of taking a URL and a schema, so
# this call needs an existing group and a valid Reworkd API key. It returns
# structured records scraped from websites only; the public API has no file upload.
if os.environ.get("REWORKD_GROUP_ID"):
    reworkd_response = requests.get(
        f"https://api.reworkd.dev/v1/outputs/{os.environ['REWORKD_GROUP_ID']}",
        headers={"Authorization": f"Bearer {os.environ['REWORKD_API_KEY']}"},
        params={"limit": 100},  # first page; metadata.next_cursor pages through the rest
        timeout=60,
    )
    reworkd_response.raise_for_status()
    records = [item["data"] for item in reworkd_response.json()["items"]]
    print(f"Reworkd returned {len(records)} structured records")

What you get back

Capability

EnConvert

Reworkd

Primary use case

Unified ingestion of web pages and files for RAG pipelines and AI agents

AI web scraping platform for structured data extraction; product sunset announced February 2025

Web page extraction

Perceive: any URL to clean Markdown, including JavaScript-rendered pages; Ingest also accepts URL lists, sitemaps, and website crawls returning the same JSONL chunk schema as file ingestion

Structured extraction through generated self-healing scrapers

File ingestion (PDF, DOCX, XLSX)

Ingest: PDF, DOCX, XLSX, CSV, Markdown, and plain text; chunks split at H1 to H3 boundaries, 512 word soft cap, tables and code blocks kept whole

Not documented as a standalone file upload ingestion API

Document conversion

Convert: 45+ conversion routes across documents, images, and data formats

Not documented

RAG-ready chunked output

Confirmed: chunks split at H1 to H3 heading boundaries, 512 word default soft cap, tables and code blocks kept whole even when they exceed the cap; each chunk carries headings_path, section, chunk_index, and word_count

Not documented

Summarisation endpoint

Distill: any URL or file to a clean summary in one call

Not documented

MCP server

Native, exposes full ingestion toolkit as MCP tools

Not documented

Free tier

500 ops per month, no card required

Not available; product sunset announced

WHY ENCONVERT FOR MULTI-FORMAT FILE INGESTION

One consistent ingestion API means the same authentication, the same output schema, and the same error handling work across web pages and files, so pipeline code does not branch by input type. Adding a new document format does not require a new integration. If you relied on Reworkd for field-level structured extraction at scale, EnConvert returns clean Markdown and heading-aware chunks rather than generated scrapers, so evaluate it against that specific need.

Get free API key — 500 ops per month, no card required.