skill

LandingAI ADE — Interactive Document Extraction

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "skill" with this command: npx skills add andrewyng/context-hub/andrewyng-context-hub-skill

LandingAI ADE — Interactive Document Extraction

Overview

Guided wizard for LandingAI's Agentic Document Extraction API. Collects all config from the user via AskUserQuestion , then executes curl commands via Bash . Never write Python — always use curl.

When to Use

  • User wants to parse a document (PDF, image, spreadsheet) into markdown

  • User wants to extract structured fields from a document

  • User wants to classify/split a multi-document PDF

  • User mentions LandingAI, ADE, vision agent, document AI

CRITICAL RULES

  • Extract and Split accept MARKDOWN, not raw files. Always parse first if the user has a PDF/image.

  • Auth is Bearer, not Basic. Header: Authorization: Bearer $VISION_AGENT_API_KEY

  • File field names: document for parse, markdown for extract/split. Never pdf , file , etc.

  • Always use -F (multipart form), never -d (JSON body).

  • Use jq -r when extracting markdown to avoid escaped/quoted strings.

  • NEVER read full output files into your context. See Token Warnings below.

TOKEN WARNINGS

Parse output is ~55,000 tokens per page (grounding bounding boxes = ~36,000 of that). 10 pages = ~550,000 tokens.

Output handling rules:

  • Always pipe curl output to a file: | jq . > output.json

  • Show a small jq summary after each operation (see Step 4)

  • If the user wants to see the full output: use cat via Bash so it displays in their terminal

  • If the user wants to analyze the output: use Bash commands (jq , grep , wc , head , tail , etc.) to query the file and return only the targeted answer. Do NOT read the whole file into context. Examples:

Count chunks by type

jq '[.chunks[] | .type] | group_by(.) | map({type: .[0], count: length})' output.json

Find chunks containing a keyword

jq '.chunks[] | select(.markdown | test("invoice"; "i")) | {id, type, markdown}' output.json

Get page count

jq '.metadata.page_count' output.json

List all unique grounding types

jq '[.grounding | to_entries[].value.type] | unique' output.json

  • Never use the Read tool on parse/extract/split output files

  • For markdown preview: head -20 on the saved .md file

Summary queries (use after every operation):

Parse (~430 tokens instead of ~55,000):

jq '{md_preview: (.markdown | .[0:500]), chunks: (.chunks | length), types: ([.chunks[].type] | unique), metadata: .metadata}' parse_output.json

Extract (~500 tokens):

jq '.extraction' extract_output.json

Split (~200 tokens):

jq '[.splits[] | {classification, pages, identifier}]' split_output.json

Workflow

digraph ade_wizard { rankdir=TB; node [shape=box];

collect_config [label="Step 1: Collect Config\n(API key, region, output dir)"];
choose_op [label="Step 2: Choose Operation" shape=diamond];
parse [label="Parse"];
extract [label="Extract"];
split [label="Split"];
parse_job [label="Parse Job (async)"];

extract_has_md [label="Has markdown already?" shape=diamond];
split_has_md [label="Has markdown already?" shape=diamond];

parse_first_e [label="Parse first → get markdown"];
parse_first_s [label="Parse first → get markdown"];
show_preview [label="Show markdown preview to user"];
show_preview_s [label="Show markdown preview to user"];

schema_choice [label="Schema: build new, load file,\nor generate from doc?" shape=diamond];
build_schema [label="Interactive schema builder\n(iterate until done)"];
load_schema [label="Load schema from file"];
gen_schema [label="Generate schema from\ndocument content"];
save_schema [label="Save schema to file?"];

split_choice [label="Split config: build new\nor load file?" shape=diamond];
build_split [label="Interactive split builder\n(iterate until done)"];
load_split [label="Load split config from file"];
save_split [label="Save split config to file?"];

run_extract [label="Run extract curl"];
run_split [label="Run split curl"];
run_parse [label="Run parse curl"];
run_job [label="Run parse job curl\n(poll if requested)"];

save_output [label="Save output to file"];

collect_config -> choose_op;
choose_op -> parse [label="Parse"];
choose_op -> extract [label="Extract"];
choose_op -> split [label="Split"];
choose_op -> parse_job [label="Parse Job"];

parse -> run_parse -> save_output;
parse_job -> run_job -> save_output;

extract -> extract_has_md;
extract_has_md -> parse_first_e [label="no"];
extract_has_md -> schema_choice [label="yes"];
parse_first_e -> show_preview -> schema_choice;
schema_choice -> build_schema [label="build"];
schema_choice -> load_schema [label="load"];
schema_choice -> gen_schema [label="generate"];
build_schema -> save_schema -> run_extract -> save_output;
load_schema -> run_extract;
gen_schema -> save_schema;

split -> split_has_md;
split_has_md -> parse_first_s [label="no"];
split_has_md -> split_choice [label="yes"];
parse_first_s -> show_preview_s -> split_choice;
split_choice -> build_split [label="build"];
split_choice -> load_split [label="load"];
build_split -> save_split -> run_split -> save_output;
load_split -> run_split;

}

Step 1: Collect Configuration

Use AskUserQuestion to gather ALL of these upfront:

Question 1 — API Key:

"What is your VISION_AGENT_API_KEY? (Type 'env' if it's already set as an environment variable)"

  • If env : use $VISION_AGENT_API_KEY in all commands. Validate with: if [ -z "$VISION_AGENT_API_KEY" ]; then echo "ERROR: VISION_AGENT_API_KEY not set"; fi

  • Otherwise: store the provided value and use it directly in commands.

Question 2 — Region:

Options: US (default) , EU

Region Base URL

US https://api.va.landing.ai

EU https://api.va.eu-west-1.landing.ai

Question 3 — Operation:

Options: Parse , Extract , Split , Parse Job (async)

Question 4 — Output Directory:

"Where should output files be saved? (e.g., ./output)"

Then mkdir -p the output directory.

Step 2: Collect Operation-Specific Inputs

For Parse

Ask:

  • "Local file path or URL?" → determines document=@/path vs document_url=https://...

  • "Split by page?" → yes adds -F "split=page"

For Extract

Ask:

  • "Local file path or URL to your document? (PDF/image for raw file, or .md if already parsed)"

  • Detect file type:

  • If .md file → use directly as markdown input, skip to schema step

  • If PDF/image → parse first, save markdown, show preview to user

  • Schema source (see Schema Builder section below)

For Split

Ask:

  • "Local file path or URL to your document?"

  • Same parse-first logic as Extract

  • Split config source (see Split Builder section below)

For Parse Job

Ask:

  • "Local file path or URL?"

  • "Poll until complete?" → yes/no

Schema Builder (for Extract)

After the user has markdown (either provided or from parsing), offer three choices via AskUserQuestion :

"How do you want to define your extraction schema?"

  • Build interactively — I'll walk you through adding fields one by one

  • Generate from document — I'll analyze the parsed markdown and suggest a schema

  • Load from file — Load a previously saved schema JSON file

Option A: Build Interactively

Loop until the user says done:

  • Ask: "Field name? (e.g., invoice_number, vendor_name, total_amount)"

  • Ask: "Field type?"

  • Options: string , number , boolean , array of strings , array of objects

  • Ask: "Description? (helps the model understand what to look for)"

  • If array of objects : recursively ask for sub-fields

  • Show the current schema so far

  • Ask: "Add another field, edit a field, remove a field, or done?"

  • Add another → repeat from step 1

  • Edit → ask which field, then re-ask type/description

  • Remove → ask which field to remove

  • Done → finalize schema

Assemble into JSON:

{ "type": "object", "properties": { "invoice_number": { "type": "string", "description": "Invoice number" }, "total_amount": { "type": "number", "description": "Total dollar amount" }, "line_items": { "type": "array", "items": { "type": "object", "properties": { "description": { "type": "string", "description": "Item description" }, "amount": { "type": "number", "description": "Line item amount" } } } } } }

Option B: Generate from Document

  • Read the parsed markdown content (from the parse output file)

  • Analyze the markdown to identify extractable fields — look for:

  • Key-value patterns: lines like Invoice #: 12345 , Name: ___ , Date: 01/15/2024

  • Table headers: column names in markdown tables suggest array-of-object fields

  • Labeled sections: Section 2: Insurance Information suggests grouped fields

  • Repeated structures: multiple similar entries suggest array types

  • Checkboxes/booleans: [x] or Yes/No fields → boolean type

  • Numeric values: amounts, totals, quantities → number type

  • Dates: any date-like content → string with date description

  • Build a JSON schema from the detected fields (use string as default type when uncertain)

  • Present the suggested schema to the user showing each field name, type, and description

  • Ask: "Does this look right? Edit any fields, or accept?"

  • Allow iterative edits (same add/edit/remove loop as Option A)

Option C: Load from File

  • Ask: "Path to your schema JSON file?"

  • Read and validate the file: cat /path/to/schema.json | jq .

  • Show it to the user for confirmation

  • Allow edits if needed

Save Schema

After finalizing (any option), ask:

"Save this schema for reuse? (provide a file path, or 'no')"

If yes:

cat << 'SCHEMA_EOF' > /path/to/schema.json { ... the schema ... } SCHEMA_EOF

Split Config Builder (for Split)

After the user has markdown, offer two choices:

"How do you want to define your split classifications?"

  • Build interactively — I'll walk you through adding categories

  • Load from file — Load a previously saved split config

Option A: Build Interactively

Loop until done:

  • Ask: "Category name? (e.g., 'Bank Statement', 'Pay Stub', 'Invoice')"

  • Ask: "Description? (what does this document type look like?)"

  • Ask: "Identifier field? (optional — a field to group/partition by, e.g., 'Account Number', 'Invoice Date'). Type 'none' to skip."

  • Show current config so far

  • Ask: "Add another category, edit one, remove one, or done?"

Assemble into JSON array:

[ { "name": "Bank Statement", "description": "Bank account activity summary over a period" }, { "name": "Pay Stub", "description": "Employee earnings and deductions", "identifier": "Pay Stub Date" }, { "name": "Invoice", "description": "Bill for goods or services", "identifier": "Invoice Number" } ]

Option B: Load from File

Same pattern as schema loading — read, validate, confirm, allow edits.

Save Split Config

After finalizing, ask:

"Save this split config for reuse?"

If yes, write to the specified path.

Step 3: Execute

Parse Command

curl -s -X POST "${BASE_URL}/v1/ade/parse"
-H "Authorization: Bearer ${API_KEY}"
-F "document=@/path/to/file.pdf"
-F "model=dpt-2-latest" | jq . > ${OUTPUT_DIR}/parse_output.json

For URL input, replace -F "document=@..." with -F "document_url=https://..." . For page splitting, add -F "split=page" .

Extract Command (after parse + schema built)

curl -s -X POST "${BASE_URL}/v1/ade/extract"
-H "Authorization: Bearer ${API_KEY}"
-F "markdown=@/path/to/parsed_markdown.md"
-F "model=extract-latest"
-F "schema=$(cat /path/to/schema.json)" | jq . > ${OUTPUT_DIR}/extract_output.json

Split Command (after parse + split config built)

curl -s -X POST "${BASE_URL}/v1/ade/split"
-H "Authorization: Bearer ${API_KEY}"
-F "markdown=@/path/to/parsed_markdown.md"
-F "model=split-latest"
-F "split_class=$(cat /path/to/split_config.json)" | jq . > ${OUTPUT_DIR}/split_output.json

Parse Job Commands

Create

JOB_ID=$(curl -s -X POST "${BASE_URL}/v1/ade/parse/jobs"
-H "Authorization: Bearer ${API_KEY}"
-F "document=@/path/to/file.pdf"
-F "model=dpt-2-latest" | jq -r '.job_id') echo "Job: $JOB_ID"

Poll

while true; do RESP=$(curl -s "${BASE_URL}/v1/ade/parse/jobs/$JOB_ID"
-H "Authorization: Bearer ${API_KEY}") STATUS=$(echo "$RESP" | jq -r '.status') echo "Status: $STATUS | Progress: $(echo "$RESP" | jq -r '.progress')" [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] && break sleep 5 done echo "$RESP" | jq . > ${OUTPUT_DIR}/job_result.json

List jobs

curl -s "${BASE_URL}/v1/ade/parse/jobs?status=completed&page=0&pageSize=10"
-H "Authorization: Bearer ${API_KEY}" | jq .

Step 4: Present Results

After execution:

  • Show the user a summary of the output (key fields, not the full JSON dump)

  • Tell them where the file was saved

  • For Extract: show the .extraction object formatted nicely

  • For Split: show each .splits[].classification with page ranges

  • Ask: "Want to run another operation on this document?"

Response Structure Reference

Parse Response

.markdown → full document markdown .chunks[] → {id, markdown, type, grounding: {box, page}} .metadata → {credit_usage, duration_ms, filename, job_id} .splits[] → {class, identifier, markdown, pages[], chunks[]}

Extract Response

.extraction → the extracted key-value pairs (matches your schema) .extraction_metadata → key-values with chunk_reference for grounding .metadata → {credit_usage, duration_ms, filename, job_id} .metadata.schema_violation_error → non-null if extraction didn't match schema

Split Response

.splits[] → {classification, identifier, markdowns[], pages[]} .metadata → {credit_usage, duration_ms, filename, page_count}

Job Response

.job_id, .status → pending|processing|completed|failed|cancelled .progress → 0.0 to 1.0 .data → full parse response when completed .output_url → presigned URL if result > 1MB (expires 1hr) .failure_reason → error details if failed

Quick Reference

Endpoint Method Path Model Input

Parse POST /v1/ade/parse

dpt-2-latest

document (file) or document_url

Extract POST /v1/ade/extract

extract-latest

markdown (file/string) or markdown_url

  • schema

Split POST /v1/ade/split

split-latest

markdown (file/string) or markdown_url

  • split_class

Create Job POST /v1/ade/parse/jobs

dpt-2-latest

document or document_url

Get Job GET /v1/ade/parse/jobs/{id}

— —

List Jobs GET /v1/ade/parse/jobs

— ?status=&page=&pageSize=

Supported Files Types

Documents PDF, PNG, JPG, JPEG, TIFF, BMP, WEBP, HEIC

Spreadsheets XLSX, CSV

Common Mistakes

Mistake Fix

Sending PDF to /extract or /split

Parse first to get markdown

Authorization: Basic

Must be Authorization: Bearer

-F "pdf=@..." or -F "file=@..."

Field is document (parse) or markdown (extract/split)

Missing @ before file path -F "document=@/path" needs the @

Using -d instead of -F

Always use -F for multipart form

Missing schema on extract Required — build one using the schema builder

Not using jq -r for markdown Avoids escaped/quoted strings in output

Sync parse for huge docs Use /v1/ade/parse/jobs for 50+ pages

Error Codes

Code Meaning Action

401 Bad/missing API key Check VISION_AGENT_API_KEY

400 Bad request Validate inputs, check file format

422 Unprocessable Invalid file type or malformed schema

429 Rate limited Wait and retry

500+ Server error Retry after a few seconds

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

get-api-docs

No summary provided by upstream source.

Repository SourceNeeds Review
General

login-flows

No summary provided by upstream source.

Repository SourceNeeds Review
General

POWPOW Integration

Register and log in to PowPow, create and manage digital humans using badges, and chat with them in real time via SSE.

Registry SourceRecently Updated
200Profile unavailable
General

ClawHub技能探索工具

ClawHub技能探索和导航工具。帮助用户快速找到所需的技能,支持关键词搜索和分类浏览。

Registry SourceRecently Updated
6350Profile unavailable