Skip to main content
POST
/
api
/
v3
/
search
curl --request POST \ --url https://api.lighton.ai/api/v3/search \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data ' { "query": "authentication system JWT tokens", "max_results": 5, "workspace_id": [ 42 ] } '
{ "results": [ { "chunk_id": "550e8400-e29b-41d4-a716-446655440000", "content": "The indemnifying party shall hold harmless and indemnify the other party...", "score": 0.92, "scores": { "text": 0.91, "vision": null, "keyword": 0.43, "multivector": 0.78, "relevance": 0.95 }, "source": { "file_id": 512, "filename": "customer-nda.pdf", "title": "Customer NDA — Nimbus Labs", "mime_type": "pdf", "size_bytes": 482113, "page_start": 3, "page_end": 4, "total_pages": 12, "tags": [ { "id": 7, "name": "confidential" } ], "content_types": [ { "path": "legal:contract:nda", "label": "Non-Disclosure Agreement", "attribute_values": { "jurisdiction": { "value": [ "FR", "US" ], "type": "multi-select" }, "is_mutual": { "value": true, "type": "boolean" }, "counterparty": { "value": "Nimbus Labs", "type": "text" } } } ], "external_metadata": null }, "workspace": { "id": 42, "name": "Legal Team" } } ] }

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

DRF serializer mixin providing content_type and attribute fields.

Compose into any request serializer via multiple inheritance::

class SearchRequestSerializer(FacetFilterFieldsMixin, serializers.Serializer):
    query = serializers.CharField(...)
    # content_type and attribute inherited from the mixin
query
string
required

Natural-language search query. Maximum 1500 characters.

Maximum string length: 1500
content_type
string[]

Filter by content type path. Multiple values are OR. Exact-or-subtree matching by default (e.g. legal matches legal, legal:contract). Wildcards: *contract* (contains), legal:contract* (prefix).

attribute
string[]

Filter by attribute value. Repeated attribute entries are ANDed; values inside one entry are ORed with | (pipe is the recommended OR delimiter — comma also works but can be ambiguous with multi-key values). Example: attribute=fiscal_year:2024|2025&attribute=status:active → (fiscal_year 2024 OR 2025) AND (status active). Formats: name (has any value), name:value (exact), name:>value / name:>=value (gt/gte), name:<value / name:<=value (lt/lte), name:prefix* (starts with, case-insensitive), name:*text* (contains, case-insensitive), name:a|b (OR). Smart dates: filing_date:2023 (year), filing_date:2023-06 (month). Type-aware: booleans (true/false), multi-select (membership check). Scoped: content_type(legal:compliance).regulation:AML.

max_results
integer
default:10

Maximum number of chunks to return after reranking. Range: 1–50.

Required range: 1 <= x <= 50
workspace_id
integer[]

Restrict search to these workspace IDs. Cannot combine with file_id.

tag_id
integer[]

Restrict to documents carrying any of these tag IDs (OR). Cannot combine with file_id.

file_id
integer[]

Restrict to specific file IDs. Cannot combine with workspace_id or tag_id.

mode
enum<string>
default:text

"text": hybrid keyword + vector search. "vision": VLM-embedded page image search.

  • text - text
  • vision - vision
Available options:
text,
vision
relevance_scoring
enum<string>

Controls the cross-encoder relevance scoring step. "scoring_and_filtering" (default): Score candidates for relevance and only return those above the quality threshold. When no candidate clears the threshold, the few best-scoring candidates are returned instead of an empty result; their scores.relevance is then below the usual threshold. "scoring_only": Score every candidate for relevance but return them all, even low-scoring ones. Useful for building your own filtering logic. "none": Skip the relevance scoring step and return all candidates unfiltered. Fastest option, useful when you handle scoring yourself. Omit the field for the default; send "none" to skip. Overrides skip_rerank when both are sent.

  • none - none
  • scoring_only - scoring_only
  • scoring_and_filtering - scoring_and_filtering
Available options:
none,
scoring_only,
scoring_and_filtering
skip_rerank
boolean

Deprecated — use relevance_scoring. true → relevance_scoring=none, false → relevance_scoring=scoring_and_filtering. Ignored when relevance_scoring is provided.

include_image
boolean
default:false

Append a base64-encoded page image to each result.

include_bboxes
boolean
default:false

Append merged bounding boxes (in PDF points, top-left origin) to each result so callers can overlay chunk highlights on PDF pages. PDF documents in text mode only — non-PDF and vision-mode results always return an empty list. Omitted from the response entirely when false.

Response

Ranked search results. Empty array if no documents match.

results
object[]
required

Ranked search results.

explain
object

Scoring breakdown. Present only when explain=true and SEARCH_EXPLAIN_MODE is enabled.