API Quickstart

This guide walks you through your first Extend API call. You’ll parse a document with the Parse endpoint and get back clean, LLM-ready markdown and structured blocks you can feed into RAG, downstream extraction, or any other step in your pipeline.


What we’re going to parse

We’ll parse a bank statement PDF with headers, an account summary, and a transactions table.

Bank statement page 1

For this guide we’ve hosted the bank statement here.

What you’ll get back:

  • Clean markdown for each page, ready to drop into an LLM prompt
  • Layout-aware blocks (text, tables, figures, key-value pairs) with their positions on the page
  • Page-level chunks you can index or post-process

For structured field extraction (pulling specific values like account numbers into typed JSON), see the Extract endpoint after this guide.


Get your API key

Create a key on the Developers page and store it in an environment variable:

$export EXTEND_API_KEY="your_api_key_here"

Install the SDK

$pip install extend-ai

Prefer raw HTTP? Use the cURL tab below and skip this step. For Maven and other install options, see the SDKs page.


Parse the document

Now let’s parse the sample document step by step. Pick your language: each tab walks through initializing the client, parsing the hosted document, and reading the result. Prefer to use your own file? Each “Parse the document” step has a tip showing how to upload it and pass the returned id instead.

1

Initialize the client

Create a client with your API key. It reads EXTEND_API_KEY from the environment variable you set earlier.

1import os
2from extend_ai import Extend
3
4client = Extend(token=os.environ["EXTEND_API_KEY"])
2

Parse the document

Pass the hosted file url to parse. This synchronous call sends the document through the pipeline (OCR, layout detection, table extraction, chunking) and returns a fully populated ParseRun.

1response = client.parse(
2 file={"url": "https://extend-public-files.s3.us-east-2.amazonaws.com/bank_statement_example.pdf"}
3)
4
5print(response.status) # PROCESSED

Want to parse your own document? Upload it first, then pass the returned file id instead of a url:

1with open("bank_statement.pdf", "rb") as f:
2 uploaded = client.files.upload(file=f)
3
4response = client.parse(file={"id": uploaded.id})
3

Read the response

output.chunks holds the parsed document. Each chunk has a content string of clean markdown and a blocks array of typed, layout-aware elements.

1for chunk in response.output.chunks:
2 print(chunk.content) # clean markdown for the chunk
3 for block in chunk.blocks:
4 print(block.type, block.content) # text, table, figure, ...

Complete code:

1import os
2from extend_ai import Extend
3
4client = Extend(token=os.environ["EXTEND_API_KEY"])
5
6response = client.parse(
7 file={"url": "https://extend-public-files.s3.us-east-2.amazonaws.com/bank_statement_example.pdf"}
8)
9print(response.status)
10
11for chunk in response.output.chunks:
12 print(chunk.content)

Understanding the response

The parsed document content lives in output.chunks. Each chunk has a content string (clean markdown for that page or section) and a blocks array of structured elements with layout coordinates.

1{
2 "object": "parse_run",
3 "id": "pr_3f1j6I1gsw5k96xFiCnkM",
4 "file": {
5 "object": "file",
6 "id": "file_GzKUy0VDhHscv7tweODYb",
7 "name": "bank_statement.pdf"
8 },
9 "status": "PROCESSED",
10 "output": {
11 "chunks": [
12 {
13 "id": "chunk_qncr8Txe-wYvmFjipXgMD",
14 "type": "page",
15 "content": "CHASE JPMorgan Chase Bank, N.A. P O Box 659754...",
16 "metadata": { "pageRange": { "start": 1, "end": 1 } },
17 "blocks": [
18 {
19 "object": "block",
20 "id": "block_WNoJ0WbMj4pRW9MpMpUox",
21 "type": "text",
22 "content": "CHASE JPMorgan Chase Bank, N.A. P O Box 659754 San Antonio, TX 78265 - 9754",
23 "details": {},
24 "metadata": { "page": { "number": 1, "width": 612, "height": 792 } },
25 "polygon": [
26 { "x": 56.873, "y": 35.374 },
27 { "x": 162.173, "y": 35.215 },
28 { "x": 162.245, "y": 81.158 },
29 { "x": 56.938, "y": 81.317 }
30 ],
31 "boundingBox": { "left": 56.873, "top": 35.215, "right": 162.245, "bottom": 81.317 }
32 }
33 ]
34 }
35 ]
36 },
37 "metrics": { "pageCount": 7, "processingTimeMs": 8293 },
38 "usage": { "credits": 14 }
39}

Key fields:

FieldWhat it contains
idUnique identifier for the parse run. Use it to fetch results later.
statusProcessing state for the run (e.g., PROCESSED).
output.chunksParsed content units (page, section, or document, based on config).
output.chunks[].contentClean markdown for the chunk, ready for an LLM.
output.chunks[].blocksIndividual elements (text, tables, figures) with their types and positions.
blocks[].typeWhat kind of element this is: text, table, figure, key_value, and more.
blocks[].boundingBoxCoordinates showing where the element appears on the page.
usage.creditsCredits consumed by this run.

Pass content straight into an LLM, or walk blocks when you need tables and spatial structure. For the complete shape, see Response Format.


Configuring the parser

The default settings work well for most documents, but you can shape the output by passing a config object. The most common options are the chunking strategy and per-block options:

1response = client.parse(
2 file={
3 "url": "https://extend-public-files.s3.us-east-2.amazonaws.com/bank_statement_example.pdf",
4 },
5 config={
6 # Group content into logical sections instead of one chunk per page
7 "chunkingStrategy": {
8 "type": "section",
9 "options": {"maxCharacters": 2000},
10 },
11 # Analyze and summarize charts, diagrams, and images
12 "blockOptions": {"figures": {"enabled": True}},
13 },
14)

What these options do:

  • chunkingStrategy.type: "page" (default), "section" (logical, heading-aware chunks for RAG), or "document" (one chunk for the whole file).
  • blockOptions: Fine-grained control over how figures, tables, and other block types are detected and formatted.

For the full list of options, see Configuration Options. You can also configure the parser visually and export the config from Extend Studio.


Next steps

You’ve parsed a document with the API. Here’s where to go next: