Reason
Grounded legal Q&A with a hallucination guard that verifies every citation.
POST /v1/reason
Requires a Pay As You Go plan — not available on Free.
Retrieves relevant chunks (same pipeline as /v1/search, rerank always on), prompts the model to answer using only that context with [[REF:canonical_id#article_no]] tokens, then verifies every token against the retrieved set before it reaches you. Invalid refs are stripped, not shown, and counted in grounding.dropped_unverified_refs — Dike never fabricates a citation to avoid an empty answer.
flowchart LR
A[Question] --> B[Retrieve + rerank<br/>same pipeline as /v1/search]
B --> C[Model answers using<br/>only retrieved context]
C --> D{Every REF token<br/>in retrieved set?}
D -->|yes| E[Marker verified<br/>shown as numbered citation]
D -->|no| F[Stripped, counted in<br/>dropped_unverified_refs]
E --> G[Response]
F --> G
Request
{
"question": "هل يجوز فسخ عقد الإيجار لتأخر المستأجر عن السداد؟",
"filters": { "jurisdiction": "EG" },
"top_k": 12,
"stream": false,
"language": "ar"
}filters accepts the same shape as /v1/search. language is "ar" (default) or "en".
Response (non-streaming)
{
"answer": "...نعم، وفقاً للمادة 157 [1] ...",
"citations": [
{
"marker": 1,
"canonical_id": "eg-leg-1948-131",
"article_no": "157",
"citation_string": "المادة 157 من القانون المدني رقم 131 لسنة 1948",
"snippet": "...",
"verified": true
}
],
"grounding": { "retrieved": 12, "used": 4, "dropped_unverified_refs": 0 },
"took_ms": 3210
}If the answer has zero verified citations and isn't the insufficient-grounding sentinel ("لا أجد سنداً قانونياً كافياً" / an equivalent English refusal), the response still returns normally with grounding.used: 0, plus a response header X-Dike-Grounding: weak — treat that header as a signal to show the answer with a caveat, not as an error.
Streaming
stream: true switches the response to text/event-stream:
data: {"token": "..."}
data: {"token": "..."}
event: citations
data: {"citations": [...], "grounding": {...}}
Token events are buffered until each [[REF:...]] token fully closes, so a REF is never split across a chunk boundary — by the time you see [1] in the stream it's already been rewritten from the raw token. The final citations event carries the same citations/grounding shape as the non-streaming response.
Errors
401 unauthorized403 plan_required— Free plan;/v1/reasonneeds Pay As You Go422 validation_error503 upstream_unavailable