Light
Ask a question and get an answer strictly from your documents, with numbered citations or an honest refusal; web search only as an explicit second step.
Light is the document assistant of Subsidia: retrieve, cite, compute, never invent. One retrieval and one strictly grounded completion per question, no memory, no persona. If your documents do not contain the answer, Light says so plainly instead of answering from general knowledge. That refusal is the feature: an answer that is always confident cannot be trusted when it matters.
Light is reachable with an API key (scope light), so you can put it behind your own interface, an internal bot or an automation.
- Question
- Scope to a dossier (named or given)
- Retrieve passages
- Strict grounded completion
- Answer with [n] citations, or refusal
- Optional: /light/web
Behaviour you can rely on
| Situation | What Light does |
|---|---|
| The passages answer the question | An answer whose claims carry [n] markers; sources lists those passages with file, section and page. |
| The documents do not cover it | The answer states, in the language of the question, that the documents do not cover it ("Les documents ne couvrent pas cette question."), and may suggest how to reformulate or which document to add. It never answers from outside knowledge. |
| Several client files hold the same document and the question does not say which | Light does not guess. It returns a question back in answer, fills ambiguity with the candidate dossiers, uses no model and no question from your allowance. Ask again with dossierId, or name the client in the question. |
| Table questions (sums, counts over a spreadsheet) | Computed deterministically; the precomputed field shows the tool, its arguments and its result. |
| Retrieval itself failed | A 503. This is an outage, not an answer: nothing was searched, so nothing is claimed or refused. |
| Personal data in the question | Masked before leaving toward an external provider; the categories are listed in masked. Local models are never masked against. |
Endpoints
POST/light/ask
Ask a question of the workspace documents.
lightAnswers only from the documents of the workspace, with numbered citations. The server keeps no conversation: to hold a dialogue, send the previous turns in history yourself.
The response carries a proofId, the id of a signed proof certificate of this turn, except when Light asked a clarifying question (no model answered).
The route lives at /light/ask (no /v1 prefix).
Request body
questionstringrequiredThe question. Trimmed; an empty value is a 400.historyobject[]Previous turns of the conversation, so a follow-up ("and for the second lease?") is understood.dossierIdstringCollection id (a client file). Restricts retrieval to that dossier. Without it, Light infers the dossier when the question or the history names one.providerstringauto,local, or a provider id allowed in the workspace. An unknown, unconfigured or disallowed value is a 400 with a code; Light never silently switches provider.
Request examples
curl https://api.subsidia.protypa.fr/light/ask \ -H "Authorization: Bearer $SUBSIDIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"question": "What is the notice period to terminate the lease?", "dossierId": "col_123"}'Responses
The answer and everything needed to cite it.
{ "answer": "The tenant may terminate at the end of each three-year period with six months' notice, by registered letter [1].", "sources": [ { "ref": 1, "sourceId": "clx9k2m4p0002abcd", "sourceName": "contrat-bail-2025.pdf", "dossierId": "col_123", "dossierName": "Dupont SARL", "section": "Article 12 - Termination", "page": 6, "chunkId": "ck_8f31a0c2", "chunkPreview": "The tenant may terminate the lease at the end of each three-year period...", "similarity": 0.81, "pinnedByUser": false } ], "masked": [], "precomputed": null, "tokensUsed": 1210, "scope": { "dossiers": [{ "id": "col_123", "name": "Dupont SARL" }], "how": "chosen" }, "ambiguity": null, "proofId": "pf_a059713a5f1c4e0b8d7a3c21e9b64f10"}Errors
- 400Empty question, or
providernot allowed. - 401Missing or invalid key.
- 402
QUESTION_LIMITThe workspace has no questions left. - 403
scope_deniedThe key lacks thelightscope. - 429
rate_limitedThe key exceeded its own requests-per-minute limit. - 503Retrieval failed.
Notes
sources[].ref matches the [n] markers in answer. scope.how is named when the dossier was inferred from the question, chosen when you passed dossierId. A clarifying turn has ambiguity set to { document, dossiers, more }, tokensUsed 0 and proofId null. The answer text may contain internal grounding rail characters in some surfaces; strip any of the four characters U+27E6, U+27E7, U+27EC, U+27ED before displaying it in your own UI.
Web fallback, only after a refusal
A web search takes the question outside the building, so it is never part of /light/ask. When Light has refused and the person agrees, call /light/web as a separate, explicit step:
- The query is redacted before it leaves (personal data, names of your dossiers), and the query actually sent is returned as
queryand written to the audit journal, so a firm can check what left the machine. - The answer comes from the fetched pages only and is returned with the page URLs as
sources. Never display it as if it came from the client's documents. - It needs web search to be configured on the server; otherwise it answers
409.
POST/light/web
Answer from the web, as an explicit follow-up to a refusal.
lightSearches the web with a redacted query and answers from the pages found, with numbered citations to those pages. Call it only when the user has chosen to go to the web.
Request body
questionstringrequiredThe question that Light refused. Redacted server-side before the search.providerstringSame meaning as on/light/ask.
Request examples
curl https://api.subsidia.protypa.fr/light/web \ -H "Authorization: Bearer $SUBSIDIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"question": "What is the legal minimum notice period for a commercial lease in France?"}'Responses
The web answer. When the search finds nothing, answer is empty, sources is empty and reachable tells you whether the search engine could be reached at all.
{ "answer": "For a commercial lease the tenant may give notice at the end of each three-year period, six months in advance [1].", "sources": [ { "ref": 1, "sourceName": "service-public.fr", "title": "Commercial lease: termination by the tenant", "url": "https://www.service-public.fr/professionnels-entreprises/vosdroits/F31125", "preview": "The tenant may terminate the lease at the end of each three-year period..." } ], "reachable": true, "query": "minimum notice period commercial lease France", "tokensUsed": 940}Errors
- 400Empty question, or
providernot allowed. - 403
scope_deniedThe key lacks thelightscope. - 409
web_search_disabledNo web search engine is configured on the server.
Light, Gateway or knowledge/query?
| You want | Use |
|---|---|
| A cited answer or an honest refusal, no prompt to write | POST /light/ask |
| The passages only, to build your own prompt, panel or check | POST /v1/knowledge/query |
| Retrieval inside an existing OpenAI or Anthropic client | Add +cortex to the model in the Gateway; the passages are committed to the certificate. |
| Check an existing text against the documents, claim by claim | The Verificateur |
Frequently asked
Does Light count against my questions?
Yes: a Light turn that reaches the model is a question of your allowance, like any answer. A clarifying turn (ambiguity) uses no model and costs nothing. Ingestion never counts. See Rate limits and quotas.
Can I keep a conversation?
The server is stateless. Send the earlier turns in history. Pinned passages and saved workbooks are features of the app, not of this API.
Why does Light refuse when I know the answer is in a file?
Check the source is ready (Knowledge sources), that you did not restrict to the wrong dossierId, and run the same question through /v1/knowledge/query to see which passages are retrieved. A refusal on a scan usually means OCR did not read it.