apyhub
Back
▣ INGESTION KIT · OUTPUT KIT

Unified Document Extraction

What it does

Unified Document Extraction turns a document URL into per-unit Markdown, with each page, slide, sheet, image, or section returned as its own record. Send a presigned_url, and you get structured text back in document order.

Use the optional filename as an extension hint for plain-text containers such as .csv, .tsv, and .md, and mime_type when you have a content-type hint. The extractor determines the real file type from the content, then routes each unit as native, ocr, mixed_ocr, native_plus_embedded_ocr, or blank.

The response includes units, metadata, and diagnostics. Each unit carries its index, kind, label, markdown, route, language, and any warnings, so you can preserve reading order and handle OCR fallbacks or hidden content explicitly. metadata reports the detected MIME type and extraction model, while diagnostics tells you whether OCR was attempted and how many embedded images were OCR’d, skipped as decorative, or left unprocessed.

Use Unified Document Extraction when you need to ingest reports, slide decks, spreadsheets, scans, or mixed-format files into downstream search, summarization, review, or indexing pipelines.

POST
Extract a document into per-unit Markdown
https://api.eu.apyverse.com/macht/extract-unified

QUICKSTART

GUIDE

Quickstart

Send a document URL for extraction and get back structured content.

curl -X POST "https://api.eu.apyverse.com/macht/extract-unified" \
  -H "apy-token: $APY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "presigned_url": "https://example-bucket.s3.amazonaws.com/safety-handbook.pdf?X-Amz-Signature=example"
  }'

What you'll get back

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

{
  "data": {
    "units": [],
    "metadata": {
      "detected_mime_type": "application/pdf",
      "model": "..."
    },
    "diagnostics": {
      "ocr_attempted": false,
      "embedded_images_total": 0,
      "embedded_images_ocrd": 0,
      "embedded_images_skipped_decorative": 0
    }
  }
}
TRY ITLIVE · 1000 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

Extracts a document from the provided URL and returns the content as per-unit Markdown, along with extraction metadata and diagnostics. The request body must include a presigned_url; optional filename and mime_type are used only as hints.

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 (an array of per-unit content objects), metadata (an object with extraction details), and diagnostics (an object with OCR/image-processing counters).

ParameterTypeMandatoryDescription
dataObjectYesWrapper object containing the extracted document content and related metadata.
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[].kindENUMYesUnit kind. Allowed values: page, sheet, slide, image, section.
data.units[].labelStringYesPage N, Slide N, sheet name, section heading, Preamble, Document, or CSV row range.
data.units[].routeENUMYesHow the unit was read. Allowed 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 rendered as Markdown tables; embedded image text appears as > [Image text: …] at its anchor.
data.units[].warningsString ArrayYesStable snake_case warning codes, if any: 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 object.
data.metadata.detected_mime_typeStringYesType detected from content; may differ from the mime_type hint.
data.metadata.modelStringYesExtraction engine/model identifiers joined with +; output is deterministic per value.
data.diagnosticsObjectYesAlways present. OCR and embedded-image diagnostics for the extraction run.
data.diagnostics.ocr_attemptedBooleanYesWhether OCR was attempted.
data.diagnostics.embedded_images_totalIntegerYesTotal embedded images encountered.
data.diagnostics.embedded_images_ocrdIntegerYesCount of embedded images OCR’d.
data.diagnostics.embedded_images_skipped_decorativeIntegerYesCount of embedded images skipped as decorative.

Notes

data.diagnostics.embedded_images_total is defined as embedded_images_ocrd + embedded_images_skipped_decorative + failed; when an embedded image OCR fails, the corresponding unit is also flagged with embedded_image_ocr_failed in data.units[].warnings.

▣ 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.