> ## Documentation Index
> Fetch the complete documentation index at: https://developers.lighton.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Parse a document to Markdown

> Convert a document into readable, structured Markdown content.

Accepts either a **file upload** (multipart/form-data) or a **document URL** (JSON body).

### Sync mode (default)
Blocks until parsing completes and returns **200** with the full markdown result.

```bash
curl -X POST https://api.lighton.ai/api/v3/parse \
  -H 'Authorization: Bearer $TOKEN' \
  -F file=@invoice.pdf
```

### Async mode (`options.async = true`)
Returns **202** immediately with a `parse_<token>` job id. Poll `GET /api/v3/parse/{id}` with that same id until `status` is `completed` or `failed`.

```bash
curl -X POST https://api.lighton.ai/api/v3/parse \
  -H 'Authorization: Bearer $TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"document": "https://example.com/report.pdf", "options": {"async": true}}'
```

For multipart uploads, pass `options` as a JSON-encoded form field: `-F 'options={"async":true}'`.

**Supported file types:** `.pdf`, `.png`, `.jpg`, `.jpeg`, `.pptx`, `.ppt`, `.odp`, `.docx`, `.odt`, `.doc`, `.html`

**Sync limits:** 20 MB file size, 15 pages.

**Async limits:** 100 MB file size, 1000 pages.



## OpenAPI

````yaml /api-reference/api-console.yaml post /api/v3/parse
openapi: 3.1.0
info:
  title: LightOn API
  version: 3.9.0 (v1)
  description: >-
    LightOn gives you an API to search, parse, and ingest documents at scale.
    Build knowledge-retrieval pipelines without managing vector databases or OCR
    models.
servers:
  - url: https://api.lighton.ai
security: []
tags:
  - name: Ask
    description: >-
      Retrieval-augmented generation: search your indexed corpus and generate an
      LLM answer grounded in the retrieved passages. Supports streaming (SSE)
      and synchronous modes.
  - name: Search
    description: >-
      Hybrid vector + text retrieval over your indexed corpus. Returns ranked
      passages with provenance (file, page range, workspace). Optional reranking
      and vision mode.
  - name: Files
    description: Upload, list, fetch, and delete documents indexed in your workspaces.
  - name: Facets
    description: >-
      Organise documents with hierarchical content types and custom attributes
      per file. Start from starter templates or build your own classification
      schema from scratch.
  - name: Tags
    description: >-
      Manage flat, company-wide labels used to scope search and group content
      across workspaces.
  - name: Workspaces
    description: >-
      Create and manage workspaces — the access-controlled containers your
      documents live in.
  - name: Parse
    description: >-
      Convert documents into structured Markdown — PDFs, images, Office files,
      and HTML. Synchronous endpoint capped at 20 MB / 15 pages.
  - name: Extract
    description: >-
      Pull typed fields out of documents using a JSON Schema you provide. Sync
      mode for small documents (≤20 MB / 15 pages); async mode for larger jobs
      (≤100 MB / 1000 pages) with polling on a job ID.
  - name: API Keys
    description: >-
      Provision and revoke API keys used to authenticate against the Console
      API.
  - name: Models
    description: >-
      List, register, update, and delete custom ML models scoped to your
      company.
paths:
  /api/v3/parse:
    post:
      tags:
        - Parse
      summary: Parse a document to Markdown
      description: >-
        Convert a document into readable, structured Markdown content.


        Accepts either a **file upload** (multipart/form-data) or a **document
        URL** (JSON body).


        ### Sync mode (default)

        Blocks until parsing completes and returns **200** with the full
        markdown result.


        ```bash

        curl -X POST https://api.lighton.ai/api/v3/parse \
          -H 'Authorization: Bearer $TOKEN' \
          -F file=@invoice.pdf
        ```


        ### Async mode (`options.async = true`)

        Returns **202** immediately with a `parse_<token>` job id. Poll `GET
        /api/v3/parse/{id}` with that same id until `status` is `completed` or
        `failed`.


        ```bash

        curl -X POST https://api.lighton.ai/api/v3/parse \
          -H 'Authorization: Bearer $TOKEN' \
          -H 'Content-Type: application/json' \
          -d '{"document": "https://example.com/report.pdf", "options": {"async": true}}'
        ```


        For multipart uploads, pass `options` as a JSON-encoded form field: `-F
        'options={"async":true}'`.


        **Supported file types:** `.pdf`, `.png`, `.jpg`, `.jpeg`, `.pptx`,
        `.ppt`, `.odp`, `.docx`, `.odt`, `.doc`, `.html`


        **Sync limits:** 20 MB file size, 15 pages.


        **Async limits:** 100 MB file size, 1000 pages.
      operationId: api_v3_parse_create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParseJsonRequest'
            examples:
              Sync—DocumentURL:
                value:
                  document: https://example.com/invoice.pdf
                summary: Sync — document URL
                description: >-
                  Provide a publicly accessible document URL. Returns 200 with
                  the markdown result.
              Async—DocumentURL:
                value:
                  document: https://example.com/report.pdf
                  options:
                    async: true
                summary: Async — document URL
                description: >-
                  Async variant of the URL-based request. Set
                  `options.async=true` in the JSON body.
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ParseMultipartRequest'
            examples:
              Sync—FileUpload:
                value:
                  file: (binary)
                summary: Sync — file upload
                description: >-
                  Upload a PDF directly for synchronous parsing. Returns 200
                  with the markdown result.
              Async—FileUpload:
                value:
                  file: (binary)
                  options: '{"async": true}'
                summary: Async — file upload
                description: >-
                  Queue the document by setting `options.async=true`. For
                  multipart, pass `options` as a JSON-encoded form field.
                  Response is 202 with a `parse_<token>` job id to poll.
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParseResponse'
              examples:
                Sync—Completed:
                  value:
                    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: invoice.pdf
                      page_count: 3
                      file_size_bytes: 245120
                      mime_type: application/pdf
                    result:
                      pages:
                        - index: 1
                          markdown: |-
                            # Invoice

                            Invoice Number: INV-2026-001
                            Date: March 15, 2026
                        - index: 2
                          markdown: |-
                            ## Terms

                            Payment is due within 30 days...
                        - index: 3
                          markdown: |-
                            ## Appendix

                            Line items continued...
                    usage:
                      pages_processed: 3
                  summary: Sync — completed
                  description: >-
                    Returned by the default (sync) path. Body contains the full
                    markdown result.
          description: Sync parse — document parsed successfully.
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParseAsyncResponse'
              examples:
                Async—Accepted:
                  value:
                    id: parse_Kg
                    status: pending
                    created_at: '2026-03-31T10:00:00+00:00'
                  summary: Async — accepted
                  description: >-
                    Returned when `options.async=true` is set. `id` is the token
                    to poll with.
          description: >-
            Async parse — job accepted. Poll `GET /api/v3/parse/{id}` with the
            returned `id` until `status` is `completed` or `failed`.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIV3ErrorResponse'
              examples:
                MissingDocument:
                  value:
                    id: null
                    code: 400
                    error: bad_request
                    detail: A file upload or document URL is required.
                    doc_url: https://developers.lighton.ai/errors#bad_request
                    fields:
                      document:
                        - error: required
                          detail: A file upload or document URL is required.
                  summary: Missing document
                PageLimitExceeded:
                  value:
                    id: null
                    code: 400
                    error: max_pages_exceeded
                    detail: >-
                      Document has 1200 pages, exceeding the async limit of 1000
                      pages.
                    doc_url: https://developers.lighton.ai/errors#max_pages_exceeded
                  summary: Page limit exceeded
          description: >-
            Bad request — missing document, unsupported format, or page limit
            exceeded (15 pages sync / 1000 pages async).
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIV3ErrorResponse'
              examples:
                Unauthorized:
                  value:
                    id: null
                    code: 401
                    error: unauthorized
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                    doc_url: https://developers.lighton.ai/errors#unauthorized
          description: Authentication credentials were not provided or are invalid
        '413':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIV3ErrorResponse'
              examples:
                PayloadTooLarge:
                  value:
                    id: null
                    code: 413
                    error: payload_too_large
                    detail: File size (157286400 bytes) exceeds the 100MB async limit.
                    doc_url: https://developers.lighton.ai/errors/payload_too_large
                  summary: Payload too large
          description: File exceeds the size limit (20 MB sync / 100 MB async).
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIV3ErrorResponse'
              examples:
                TooManyRequests:
                  value:
                    id: null
                    code: 429
                    error: too_many_requests
                    detail: Too many requests. Please try again later.
                    doc_url: https://developers.lighton.ai/errors#too_many_requests
                  summary: Too Many Requests
          description: Too many requests
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIV3ErrorResponse'
              examples:
                ServiceUnavailable:
                  value:
                    id: null
                    code: 503
                    error: service_unavailable
                    detail: VLM backend is overloaded. Retry later.
                    doc_url: https://developers.lighton.ai/errors/service_unavailable
                  summary: Service unavailable
          description: VLM backend is overloaded. Retry later.
      security:
        - bearerAuth: []
components:
  schemas:
    ParseJsonRequest:
      type: object
      properties:
        document:
          type: string
          format: uri
          description: Publicly accessible URL of the document to parse.
        options:
          type: object
          properties:
            async:
              type: boolean
              default: false
              description: >-
                Queue the document for asynchronous parsing and return 202 with
                a job id.
          additionalProperties: true
          description: >-
            Parse options. Currently supports `{"async": true}` to queue the
            document.
      required:
        - document
    ParseMultipartRequest:
      type: object
      properties:
        file:
          type: string
          format: binary
          description: The document to parse.
        options:
          type: object
          properties:
            async:
              type: boolean
              default: false
              description: >-
                Queue the document for asynchronous parsing and return 202 with
                a job id.
          additionalProperties: true
          description: >-
            Parse options as a JSON-encoded string. Currently supports
            `{"async": true}` to queue the document.
      required:
        - file
    ParseResponse:
      type: object
      description: >-
        Synchronous ``POST /api/v3/parse`` response — the parse completed
        inline.
      properties:
        id:
          type: string
        status:
          type: string
        created_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        processing_time_ms:
          type: integer
        document:
          $ref: '#/components/schemas/ParseDocument'
        result:
          $ref: '#/components/schemas/ParseResult'
        usage:
          $ref: '#/components/schemas/ParseUsage'
      required:
        - completed_at
        - created_at
        - document
        - id
        - processing_time_ms
        - result
        - status
        - usage
    ParseAsyncResponse:
      type: object
      description: >-
        Returned by ``POST /api/v3/parse`` with ``options.async=true`` — caller
        polls ``GET /api/v3/parse/<id>``.
      properties:
        id:
          type: string
          description: Parse job id (e.g. `parse_Kg`); poll via GET /api/v3/parse/<id>.
        status:
          type: string
          description: Initial status — typically 'pending'.
        created_at:
          type: string
          format: date-time
          description: When the job was accepted.
      required:
        - created_at
        - id
        - status
    APIV3ErrorResponse:
      type: object
      properties:
        id:
          type:
            - string
            - 'null'
          description: >-
            Job/resource id when one already exists (useful for async error
            diagnosis); null otherwise.
        code:
          type: integer
          description: HTTP status code
        error:
          type: string
          description: Error code used by the UI as a translation key
        detail:
          type: string
          description: Human-readable error message for developers
        doc_url:
          type: string
          description: Link to the error-code documentation page
      required:
        - code
        - detail
        - doc_url
        - error
        - id
    ParseDocument:
      type: object
      properties:
        filename:
          type: string
        page_count:
          type:
            - integer
            - 'null'
        file_size_bytes:
          type: integer
        mime_type:
          type: string
      required:
        - file_size_bytes
        - filename
        - mime_type
        - page_count
    ParseResult:
      type: object
      properties:
        pages:
          type: array
          items:
            $ref: '#/components/schemas/Page'
      required:
        - pages
    ParseUsage:
      type: object
      properties:
        pages_processed:
          type: integer
      required:
        - pages_processed
    Page:
      type: object
      description: >-
        Canonical per-page document text object.


        Originates with /parse and is reused by /ocr and /files (the latter
        imports it

        from here) so a client can switch between live parsing and reading an

        already-ingested file without reshaping page data. Defined once and
        reused

        everywhere — never redefine this shape per app.


        Extensible: future per-page fields (tables, images, confidence, ...) can
        be

        added here without breaking callers that only consume ``index`` +
        ``markdown``.
      properties:
        index:
          type: integer
          description: Page number within the document (1-based).
        markdown:
          type: string
          description: Page text rendered as Markdown.
      required:
        - index
        - markdown
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer authentication header of the form `Bearer <token>`, where
        `<token>` is your auth token.

````