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

# Extract structured data from a document

> Pull specific fields from a document into a typed schema.

Accepts either a **file upload** (multipart/form-data) or a **document URL** (JSON body), plus a **JSON Schema** (the `schema` field) describing what to extract.

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

```bash
curl -X POST https://api.lighton.ai/api/v3/extract \
  -H 'Authorization: Bearer $TOKEN' \
  -F file=@invoice.pdf \
  -F 'schema={"type":"object","properties":{"invoice_number":{"type":"string"}}}'
```

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

```bash
curl -X POST https://api.lighton.ai/api/v3/extract \
  -H 'Authorization: Bearer $TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"document": "https://example.com/report.pdf", "schema": {"type": "object", "properties": {"title": {"type": "string"}}}, "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/extract
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/extract:
    post:
      tags:
        - Extract
      summary: Extract structured data from a document
      description: >-
        Pull specific fields from a document into a typed schema.


        Accepts either a **file upload** (multipart/form-data) or a **document
        URL** (JSON body), plus a **JSON Schema** (the `schema` field)
        describing what to extract.


        ### Sync mode (default)

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


        ```bash

        curl -X POST https://api.lighton.ai/api/v3/extract \
          -H 'Authorization: Bearer $TOKEN' \
          -F file=@invoice.pdf \
          -F 'schema={"type":"object","properties":{"invoice_number":{"type":"string"}}}'
        ```


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

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


        ```bash

        curl -X POST https://api.lighton.ai/api/v3/extract \
          -H 'Authorization: Bearer $TOKEN' \
          -H 'Content-Type: application/json' \
          -d '{"document": "https://example.com/report.pdf", "schema": {"type": "object", "properties": {"title": {"type": "string"}}}, "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_extract_create
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/ExtractRequest'
            examples:
              ExtractViaFileUpload(sync):
                value:
                  file: (binary)
                  schema:
                    type: object
                    properties:
                      invoice_number:
                        type: string
                summary: Extract via file upload (sync)
                description: >-
                  Upload a PDF and provide a JSON Schema to extract specific
                  fields.
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ExtractRequest'
          application/json:
            schema:
              $ref: '#/components/schemas/ExtractRequest'
            examples:
              ExtractViaDocumentURL(sync):
                value:
                  document: https://example.com/invoice.pdf
                  schema:
                    type: object
                    properties:
                      invoice_number:
                        type: string
                        description: The invoice reference number
                      total:
                        type: number
                        description: The total amount due
                summary: Extract via document URL (sync)
                description: Provide a publicly accessible document URL and a JSON Schema.
              ExtractAsynchronously:
                value:
                  document: https://example.com/large-report.pdf
                  schema:
                    type: object
                    properties:
                      title:
                        type: string
                  options:
                    async: true
                summary: Extract asynchronously
                description: >-
                  Same as above with options.async=true. Returns 202 with a job
                  ID.
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExtractJobResponse'
              examples:
                SyncExtractionResponse:
                  value:
                    id: ext_0196e4b2a3c14d5e8f7a9b2c1d0e3f4a
                    status: completed
                    created_at: '2026-03-31T10:00:00+00:00'
                    completed_at: '2026-03-31T10:00:04+00:00'
                    processing_time_ms: 3200
                    document:
                      filename: invoice.pdf
                      page_count: 3
                      file_size_bytes: 245120
                      mime_type: application/pdf
                    result:
                      data:
                        - invoice_number: INV-2026-001
                          total: null
                          line_items: null
                        - invoice_number: null
                          total: 1250
                          line_items:
                            - description: Widget A
                              quantity: 10
                              unit_price: 50
                            - description: Widget B
                              quantity: 5
                              unit_price: 150
                        - invoice_number: null
                          total: null
                          line_items: null
                      pagination:
                        page: 1
                        page_size: 15
                        total_items: 3
                        total_pages: 1
                        has_next: false
                        has_prev: false
                    usage:
                      pages_processed: 3
                    progress:
                      percentage: 100
                      pages_processed: 3
                  summary: Sync extraction response
          description: Extraction completed (sync mode).
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExtractJobResponse'
              examples:
                AsyncAcceptedResponse:
                  value:
                    id: ext_0196e4b2a3c14d5e8f7a9b2c1d0e3f4a
                    status: pending
                    created_at: '2026-03-31T10:00:00+00:00'
                    completed_at: null
                    processing_time_ms: null
                    document:
                      filename: large-report.pdf
                      page_count: null
                      file_size_bytes: 5242880
                      mime_type: application/pdf
                    result: null
                    usage: null
                    progress: null
                  summary: Async accepted response
          description: >-
            Extraction accepted (async mode). Poll GET /v3/extract/{id} for
            status.
        '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/file, unsupported format, or page
            limit exceeded.
        '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).
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIV3ValidationErrorResponse'
              examples:
                MalformedJSONSchema:
                  value:
                    id: null
                    code: 422
                    error: validation_error
                    detail: The provided JSON Schema is malformed.
                    doc_url: https://developers.lighton.ai/errors#validation_error
                    fields:
                      schema:
                        - error: invalid
                          detail: 'JSON Schema is not valid: missing ''type'' keyword.'
                  summary: Malformed JSON Schema
          description: >-
            JSON Schema is malformed, uses unsupported features, or exceeds
            limits.
        '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_overloaded
                    detail: Parsing backend is at capacity. Retry later.
                    doc_url: https://developers.lighton.ai/errors/service_overloaded
                  summary: Service unavailable
          description: Parsing backend is overloaded. Retry later.
      security:
        - bearerAuth: []
components:
  schemas:
    ExtractRequest:
      description: >-
        Body for POST /api/v3/extract.


        ``schema`` is the JSON Schema that drives extraction. It arrives as a
        dict

        on JSON requests and as a JSON-encoded string on multipart requests —
        both

        are coerced to ``dict``.


        ``options`` is a free-form dict; currently supports ``{"async": bool}``.
      properties:
        document:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Document
        schema:
          additionalProperties: true
          title: Schema
          type: object
        options:
          additionalProperties: true
          title: Options
          type: object
      required:
        - schema
      title: ExtractRequest
      type: object
    ExtractJobResponse:
      properties:
        id:
          title: Id
          type: string
        status:
          title: Status
          type: string
        created_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          default: null
          title: Created At
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          default: null
          title: Completed At
        processing_time_ms:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          title: Processing Time Ms
        document:
          anyOf:
            - $ref: '#/components/schemas/ExtractDocument'
            - type: 'null'
          default: null
        result:
          anyOf:
            - $ref: '#/components/schemas/ExtractResult'
            - type: 'null'
          default: null
        usage:
          anyOf:
            - $ref: '#/components/schemas/ExtractUsage'
            - type: 'null'
          default: null
        progress:
          anyOf:
            - $ref: '#/components/schemas/JobProgress'
            - type: 'null'
          default: null
      required:
        - id
        - status
      title: ExtractJobResponse
      type: object
    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
    APIV3ValidationErrorResponse:
      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
        fields:
          type: object
          additionalProperties:
            type: array
            items:
              $ref: '#/components/schemas/APIV3FieldError'
          description: Field-level validation errors keyed by field name
      required:
        - code
        - detail
        - doc_url
        - error
        - id
    ExtractDocument:
      properties:
        filename:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Filename
        page_count:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          title: Page Count
        file_size_bytes:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          title: File Size Bytes
        mime_type:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Mime Type
      title: ExtractDocument
      type: object
    ExtractResult:
      properties:
        data:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          default: null
          title: Data
        pagination:
          anyOf:
            - $ref: '#/components/schemas/ExtractPagination'
            - type: 'null'
          default: null
      title: ExtractResult
      type: object
    ExtractUsage:
      properties:
        pages_processed:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          title: Pages Processed
      title: ExtractUsage
      type: object
    JobProgress:
      description: >-
        Live progress of a long-running async job while it is in flight.


        Shared by the parse (``GET /api/v3/parse/<id>``) and extract

        (``GET /api/v3/extract/<id>``) polling envelopes: ``pages_processed`` is
        the

        count of pages done so far and ``percentage`` is the completion
        percentage

        [0, 100] derived from it.
      properties:
        percentage:
          title: Percentage
          type: integer
        pages_processed:
          title: Pages Processed
          type: integer
      required:
        - percentage
        - pages_processed
      title: JobProgress
      type: object
    APIV3FieldError:
      type: object
      properties:
        error:
          type: string
          description: Error code / translation key
        detail:
          type: string
          description: Human-readable description of the field error
      required:
        - detail
        - error
    ExtractPagination:
      properties:
        page:
          title: Page
          type: integer
        page_size:
          title: Page Size
          type: integer
        total_items:
          title: Total Items
          type: integer
        total_pages:
          title: Total Pages
          type: integer
        has_next:
          title: Has Next
          type: boolean
        has_prev:
          title: Has Prev
          type: boolean
      required:
        - page
        - page_size
        - total_items
        - total_pages
        - has_next
        - has_prev
      title: ExtractPagination
      type: object
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer authentication header of the form `Bearer <token>`, where
        `<token>` is your auth token.

````