apyhub
Back
▣ INGESTION KIT · DOCUMENT INTELLIGENCE KIT

Unified Document Extraction API

Hosted on ApyHub

What it does

Document Markdown Extractor turns an uploaded document into per-unit Markdown. Send a presigned_url, with optional filename and mime_type hints, and get back a document-order breakdown of units that you can join into the full text.

Each unit includes an index, kind, label, markdown, route, language, and warnings. That gives you both the extracted content and the context needed to rebuild page-by-page, slide-by-slide, sheet-by-sheet, or section-by-section output. The extractor also returns metadata with the detected MIME type and extraction model, plus diagnostics for OCR activity and embedded image handling.

Use Document Markdown Extractor when you need document content that is easier to search, chunk, review, or feed into downstream processing than the original file. It handles native text, OCR fallback, and embedded image text, while preserving stable warning codes such as ocr_fallback_used, table_split_into_blocks, and embedded_image_ocr_failed.

For PDFs, spreadsheets, slides, images, and text containers, you get a consistent Markdown representation without having to build your own parsing pipeline.

POST
Extract a document into per-unit Markdown
https://api.eu.apyhub.com/apyhub/unified-document-extraction

QUICKSTART

GUIDE

Quickstart

Send a presigned file URL so the API can extract its content.

curl -X POST "https://api.eu.apyhub.com/apyhub/unified-document-extraction" \
  -H "apy-token: $APY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "presigned_url": "https://assets.apyhub.com/samples/sample.pdf",
    "filename": "sample.pdf",
    "mime_type": "application/pdf"
  }'

What you'll get back

Returns a JSON object with a data object. data contains units (the extracted content units in document order), metadata (the detected MIME type and model), and diagnostics (OCR and embedded-image counts).

{
  "data": {
    "units": [
      {
        "index": 1,
        "kind": "page",
        "label": "Page 1",
        "markdown": "Adobe Acrobat PDF Files Adobe® Portable...",
        "route": "native",
        "language": "en",
        "warnings": []
      }
    ],
    "metadata": {
      "detected_mime_type": "application/pdf",
      "model": "apyhub-unified/v1"
    },
    "diagnostics": {
      "ocr_attempted": false,
      "embedded_images_total": 0,
      "embedded_images_ocrd": 0,
      "embedded_images_skipped_decorative": 0
    }
  }
}
TRY ITLIVE · 10 ATOMS
Loading your default key…
The full key is used to call the gateway and stays in this tab — never sent to orbit or saved.
body*
S3 presigned GET URL (or any http/https URL). Fetched as-is; may exceed 2,048 characters. Never logged.
Optional. Used only as an extension hint for plain-text containers (.csv, .tsv, .md) and image naming.
MIME type hint. Never trusted — routing uses the type detected from content.

About this endpoint

What it does

Uploads a document via a presigned URL and returns its extracted content as per-unit Markdown, along with metadata and diagnostics about the extraction process.

Request Body

ParameterTypeMandatoryDescription
filenameStringNoOptional. Used only as an extension hint for plain-text containers (.csv, .tsv, .md) and image naming.
mime_typeStringNoMIME type hint. Never trusted — routing uses the type detected from content.
presigned_urlStringYesS3 presigned GET URL (or any http/https URL). Fetched as-is; may exceed 2,048 characters. Never logged.

Response

Returns a JSON object with a data object field. data contains units, metadata, and diagnostics; units is an array of content units in document order, metadata describes the extraction engine and detected MIME type, and diagnostics reports OCR/image processing counters.

ParameterTypeMandatoryDescription
dataObjectYesContainer for the extraction result. Includes units, metadata, and diagnostics.
data.unitsObject ArrayYesThe whole content contract, in document order. Join markdown in order for the full document. Each unit includes index, kind, label, route, language, markdown, and warnings.
data.units[].indexIntegerYesContiguous 1-based position; maps to chunk page_number.
data.units[].kindENUMYesAllowed values: page, sheet, slide, image, section.
data.units[].labelStringYesPage N, Slide N, sheet name, section heading, Preamble, Document, or CSV row range.
data.units[].routeENUMYesAllowed values: native, ocr, mixed_ocr, native_plus_embedded_ocr, blank. A unit with empty Markdown is always blank.
data.units[].languageStringYesISO 639-1 code detected per unit; und when undetermined.
data.units[].markdownStringYesUnit content. Tables are returned as Markdown tables; embedded image text appears as > [Image text: …] at its anchor.
data.units[].warningsString ArrayYesStable snake_case codes such as hidden_sheet, hidden_rows, hidden_slide, table_split_into_blocks, embedded_image_ocr_failed, ocr_fallback_used, ocr_failed_text_layer_used, ocr_attempted_no_content, ocr_not_attempted.
data.metadataObjectYesExtraction metadata. Includes detected_mime_type and model.
data.metadata.modelStringYesExtraction engine/model identifiers joined with +; output is deterministic per value.
data.metadata.detected_mime_typeStringYesType detected from content; may differ from the mime_type hint.
data.diagnosticsObjectYesAlways present diagnostic counters for OCR and embedded image handling.
data.diagnostics.ocr_attemptedBooleanYesIndicates whether OCR was attempted.
data.diagnostics.embedded_images_totalIntegerYesTotal embedded images processed or skipped.
data.diagnostics.embedded_images_ocrdIntegerYesCount of embedded images OCR’d.
data.diagnostics.embedded_images_skipped_decorativeIntegerYesCount of embedded images skipped because they were decorative.

Notes

data.diagnostics is always present, and embedded_images_total follows the relationship embedded_images_total = embedded_images_ocrd + embedded_images_skipped_decorative + failed; any failed embedded-image OCR is also reported on the relevant unit with the embedded_image_ocr_failed warning.

▣ COMMON ERRORS

Errors any endpoint can return

400bad_request

Required parameter missing or malformed body.

401unauthorized

API key missing, revoked, or not authorized for this service.

429rate_limited

Your plan's per-second rate exceeded. Retry with exponential backoff.

503upstream_busy

Backend temporarily unavailable. Try again in a few seconds.