Skip to main content
Illustration of the Parse use case.
Parse converts a document to structured Markdown without storing or indexing it. By default the call is synchronous: send a file, get Markdown back immediately. For larger documents, an async mode queues the job and lets you poll for the result. Use Parse when you want the text content of a document for your own purposes: feeding it to an LLM, storing it in your database, displaying it in a UI, or pre-processing it before ingestion. Nothing is saved on LightOn’s side.
If you want the document to be searchable, use Files instead: it ingests and indexes the document permanently. The full schema for POST /api/v3/parse is in the API reference.

Parse a document

import requests

response = requests.post(
    "https://api.lighton.ai/api/v3/parse",
    headers={"Authorization": "Bearer $LIGHTON_API_KEY"},
    files={"file": open("report.pdf", "rb")},
)

pages = response.json()["result"]["pages"]
# Each page is {"index": <int>, "markdown": <str>}. Join them for the full document:
markdown = "\n\n".join(page["markdown"] for page in pages)
print(markdown[:200])
# → # Q4 Financial Report\n\n## Executive Summary\n\nRevenue grew 18%…
file (multipart) and document (JSON URL) are mutually exclusive: pass one or the other.

What comes back

The response includes the parsed Markdown, broken out per page, along with metadata about the original document:
{
  "id": "parse_0196e4b2a3c14d5e8f7a9b2c1d0e3f4a",
  "status": "completed",
  "created_at": "2026-03-31T10:00:00+00:00",
  "completed_at": "2026-03-31T10:00:03+00:00",
  "processing_time_ms": 2840,
  "document": {
    "filename": "report.pdf",
    "page_count": 3,
    "file_size_bytes": 245120,
    "mime_type": "application/pdf"
  },
  "result": {
    "pages": [
      { "index": 1, "markdown": "# Invoice\n\nInvoice Number: INV-2026-001\nDate: March 15, 2026\n…" },
      { "index": 2, "markdown": "## Line items\n\n| Item | Qty | Price |\n…" },
      { "index": 3, "markdown": "## Totals\n\nSubtotal: …" }
    ]
  },
  "usage": {
    "pages_processed": 3
  }
}
result.pages is an array, one entry per page, each with a 1-based index and the markdown for that page. Headings, lists, tables, and code blocks are preserved where the source document supports them. Concatenate the per-page markdown (in index order) to reconstruct the full document.

Large documents: async mode

Sync mode is capped at 20 MB / 15 pages. For larger documents, set options.async = true. The call returns 202 immediately with a parse_<token> job id instead of blocking, and you poll GET /api/v3/parse/{id} until the job reaches a terminal status.
response = requests.post(
    "https://api.lighton.ai/api/v3/parse",
    headers={"Authorization": "Bearer $LIGHTON_API_KEY"},
    json={
        "document": "https://example.com/large-report.pdf",
        "options": {"async": True},
    },
)
job_id = response.json()["id"]  # e.g. "parse_Kg"
For multipart uploads, pass options as a JSON-encoded form field: -F 'options={"async":true}'. The polling response uses the same envelope as the sync result: result, usage, completed_at, and processing_time_ms are null while the job is in flight and populated once status is completed. On terminal failure, status is failed and an error block describes the cause.
Recommended polling cadence: every 1s for the first 10s, then every 5s, capped at 30s. Stop once status is completed or failed.

Supported formats and limits

Formats: .pdf, .png, .jpg, .jpeg, .pptx, .ppt, .odp, .docx, .odt, .doc, .html
ModeMax file sizeMax pages
Sync (default)20 MB15 pages
Async (options.async = true)100 MB1000 pages
To make a document searchable rather than just converting it once, ingest it with Files and retrieve relevant sections with Search.

Common errors

StatusCause
400Missing document, unsupported format, or page limit exceeded
401Missing or invalid API key
413File exceeds the size limit for the mode (20 MB sync / 100 MB async)
429Rate limit exceeded
503Parsing backend is overloaded. Retry later