---
name: Lighton
description: Use when building document intelligence workflows: ingesting documents into searchable indexes, retrieving relevant passages via semantic/lexical search, generating grounded answers with citations, parsing documents to Markdown, extracting structured data from forms and invoices, or organizing documents with workspaces, tags, and metadata facets. Reach for LightOn when you need RAG (retrieval-augmented generation) without managing vector databases or OCR pipelines.
metadata:
    mintlify-proj: lighton
    version: "1.0"
---

# LightOn API Skill

## Product summary

LightOn is a document intelligence API that handles search, parsing, and extraction at scale without requiring you to manage vector databases or OCR models. The core workflow is: upload documents to a workspace, search them with hybrid semantic+lexical retrieval, and generate grounded answers with citations. All endpoints live under `/api/v3/` and require bearer token authentication. The Python SDK (`lighton-sdk`) wraps the REST API with typed models and automatic rate-limit pacing. Key endpoints: `POST /api/v3/files` (ingest), `POST /api/v3/search` (retrieve), `POST /api/v3/ask` (RAG), `POST /api/v3/parse` (document-to-markdown), `POST /api/v3/extract` (structured extraction). See https://developers.lighton.ai for full documentation.

## When to use

Reach for LightOn when:
- Building a searchable knowledge base from PDFs, Office files, or images
- Implementing retrieval-augmented generation (RAG) without managing embeddings or vector stores
- Answering questions grounded in documents with citations
- Parsing documents to clean Markdown for downstream processing
- Extracting typed fields from forms, invoices, or contracts using JSON Schema
- Organizing documents across teams with workspaces, or tagging cross-cutting collections
- Classifying documents with hierarchical metadata (facets) and filtering search by those attributes
- Integrating document retrieval into agentic loops or multi-step reasoning workflows

Do not use LightOn for: general-purpose LLM inference (use the Ask endpoint only for single-turn Q&A), real-time streaming of large document ingestion, or managing access control at the document level (use workspaces for tenant isolation instead).

## Quick reference

### Authentication
All requests require `Authorization: Bearer $LIGHTON_API_KEY` header. Create keys via console or `POST /api/v3/keys`. Keys can be scoped to specific workspaces with per-workspace roles (viewer, editor, owner).

### Core endpoints

| Endpoint | Method | Purpose | Sync limit | Async limit |
|----------|--------|---------|-----------|------------|
| `/api/v3/files` | POST | Upload document to workspace | — | 100 MB, 1000 pages |
| `/api/v3/search` | POST | Hybrid search (vector + lexical + rerank) | — | — |
| `/api/v3/ask` | POST | Search + LLM generation in one call | — | — |
| `/api/v3/parse` | POST | Document to Markdown | 20 MB, 15 pages | 100 MB, 1000 pages |
| `/api/v3/extract` | POST | Document to typed fields (JSON Schema) | 20 MB, 15 pages | 100 MB, 1000 pages |
| `/api/v3/workspaces` | POST/GET | Create/list isolated document containers | — | — |
| `/api/v3/tags` | POST/GET | Create/list flat document labels | — | — |
| `/api/v3/content-types` | POST/GET | Define/list hierarchical metadata schemas | — | — |

### File status values
- `pending`: upload received, indexing queued
- `embedded`: indexing complete, document searchable
- `failed`: indexing failed (check error details)
- `status_vision`: vision embeddings for image/diagram search (optional)

### Search scoping parameters
Use one or a combination:
- `workspace_id: [42, 43]` — search specific workspaces
- `tag_id: [7]` — search tagged collection
- `file_id: [101, 102]` — search specific files (mutually exclusive with workspace/tag)
- `content_type: "legal:contract:nda"` — filter by facet classification (colon-separated path)
- `attribute: "status:active|pending&fiscal_year:2024"` — filter by facet attributes (pipe=OR, ampersand=AND)

### Python SDK quick start
```python
from lighton import LightOn, Workspace, File

# Read LIGHTON_API_KEY from environment
with LightOn() as client:
    # Create workspace
    ws = Workspace(name="Docs").create(client)
    
    # Ingest files
    doc = ws.ingest(File(path="handbook.pdf"))
    doc.wait()  # poll until status == "embedded"
    
    # Search
    results = client.search("vacation policy", workspaces=[ws.id])
    for r in results.results:
        print(r.content, r.score)
    
    # Ask (search + generate)
    answer = client.ask("What is the vacation policy?", workspaces=[ws.id])
    print(answer.answer)
```

### Error response format
All errors return JSON with: `code` (HTTP status), `error` (machine-readable code), `detail` (human-readable message), `doc_url` (link to error docs). Validation errors (422) include `fields` dict with per-field error codes.

## Decision guidance

### Search vs Ask
| Scenario | Use Search | Use Ask |
|----------|-----------|---------|
| Single-turn question answering | ✗ | ✓ |
| Multi-step retrieval or conversational context | ✓ | ✗ |
| Custom prompt or model choice | ✓ | ✗ |
| Need raw passages for display/ranking | ✓ | ✗ |
| Want answer + citations in one call | ✗ | ✓ |

### Parse vs Extract
| Scenario | Use Parse | Use Extract |
|----------|-----------|------------|
| Convert document to readable text | ✓ | ✗ |
| Pull specific typed fields | ✗ | ✓ |
| Mechanical, repetitive processing (invoices, forms) | ✗ | ✓ |
| Feed text to your own LLM | ✓ | ✗ |
| One structured object per document | ✗ | ✗ (use Search + your LLM) |

### Workspace vs Tag vs Facet
| Use case | Workspace | Tag | Facet |
|----------|-----------|-----|-------|
| Isolate teams/customers/tenants | ✓ | ✗ | ✗ |
| Cross-cutting collections | ✗ | ✓ | ✗ |
| Precise structured queries | ✗ | ✗ | ✓ |
| Permission boundary | ✓ | ✗ | ✗ |
| Setup cost | Low | Low | Design taxonomy first |

## Workflow

### Build a searchable knowledge base
1. **Create a workspace** (or use default): `POST /api/v3/workspaces` with name and optional datasource config
2. **Upload documents**: `POST /api/v3/files` with workspace_id and file multipart; returns file_id and status=pending
3. **Wait for indexing**: Poll `GET /api/v3/files/{id}` until status is embedded (typically seconds to minutes)
4. **Search**: `POST /api/v3/search` with query and workspace_id; returns ranked chunks with scores and sources
5. **Ask questions**: `POST /api/v3/ask` with query and workspace_id; returns answer + sources

### Classify documents with facets
1. **Define content types**: `POST /api/v3/content-types` with action=define_content_type, path (e.g. "legal:contract:nda"), and attributes (name, type, choices)
2. **Classify files**: `POST /api/v3/files/{id}/facets` with content_type and attribute values
3. **Filter search**: Add `content_type` and `attribute` to search/ask requests to narrow results by metadata

### Extract structured data from a document
1. **Prepare JSON Schema**: Define the fields you want (e.g. `{"type": "object", "properties": {"invoice_number": {"type": "string"}}}`)
2. **Call extract**: `POST /api/v3/extract` with file (or file_id or document URL) and schema
3. **For large files**: Set `options.async = true`, get job id, poll `GET /api/v3/extract/{id}` until status=completed
4. **Parse result**: Extract applies schema to every page; result.data is array of objects (one per page)

### Agentic RAG loop (multi-step retrieval)
1. **Initialize**: Create LLM with Search as a tool
2. **Loop**: Model proposes query → call `POST /api/v3/search` → hand passages back to model → model decides to search again or answer
3. **Exit**: Model stops calling Search tool; its final message is the grounded answer

## Common gotchas

- **API key shown only once**: When you create a key via `POST /api/v3/keys`, the full key is in the response and never shown again. Store it immediately.
- **Workspace scoping**: API keys can be scoped to specific workspaces with per-workspace roles. A global key reaches all workspaces you can access; a scoped key only reaches the listed workspaces.
- **file_id is mutually exclusive**: You cannot combine `file_id` with `workspace_id` or `tag_id` in search/ask. Use one or the other.
- **Facet attribute names must be unique**: Attribute names must be unique across the entire content-type tree (root to leaves), not just within a node.
- **Content-type depth limit**: Facet trees cannot exceed 4 levels deep (e.g. `legal:contract:nda:mutual` is max). Restructure if you hit this.
- **Sync mode size limits**: Parse and Extract are capped at 20 MB / 15 pages in sync mode. Use async mode (`options.async = true`) for larger documents.
- **Relevance scoring unavailable**: If the reranker is temporarily down, results return with `warnings` array and `scores.relevance = null`. Fallback to combined retrieval score.
- **Vision mode requires vision index**: Search in vision mode only works if documents were indexed with vision embeddings (`status_vision: "embedded"`). Text mode always works.
- **Ask is single-turn only**: Ask runs one retrieval and one generation with a fixed prompt. For multi-step reasoning, use Search inside your own agentic loop.
- **Batch errors include index**: Batch endpoints return `index` field (0-based position) when an action fails. Actions before the index are committed; re-send the batch after fixing.
- **Polling cadence**: For async jobs (parse, extract), poll every 1s for first 10s, then every 5s, capped at 30s. Stop when status is completed or failed.

## Verification checklist

Before submitting work with LightOn:

- [ ] API key is set in environment (`LIGHTON_API_KEY`) and not hardcoded
- [ ] All requests include `Authorization: Bearer $LIGHTON_API_KEY` header (or SDK handles it)
- [ ] Workspace exists and file is uploaded before searching (check file status is `embedded`)
- [ ] Search/Ask scoping is correct (no conflicting `file_id` + `workspace_id`/`tag_id`)
- [ ] For async jobs (parse, extract, large file ingestion), polling loop handles both `completed` and `failed` statuses
- [ ] Error responses are checked for `error` code and `detail` message; validation errors check `fields` dict
- [ ] Facet content-type paths use colon-separated format (e.g. `legal:contract:nda`)
- [ ] Extract JSON Schema is valid and uses only supported field types
- [ ] Ask model parameter is one of: `mistral-large-latest` (default) or `alfred-ft5`
- [ ] For vision search, documents have `status_vision: "embedded"` before querying in vision mode
- [ ] Rate limits are respected (429 responses trigger backoff; SDK handles this automatically)

## Resources

**Comprehensive navigation:** https://developers.lighton.ai/llms.txt

**Critical documentation pages:**
- [Quickstart](https://developers.lighton.ai/quickstart) — upload, wait, search in 5 minutes
- [API Reference](https://developers.lighton.ai/api-reference/introduction) — complete endpoint schemas
- [From documents to answers](https://developers.lighton.ai/tutorials/from-documents-to-answers) — RAG concepts and endpoint mapping

---

> For additional documentation and navigation, see: https://developers.lighton.ai/llms.txt