Execute grounded legal reasoning over retrieved MENA legal corpora. Every citation emitted in the generated answer is strictly checked against retrieved statutes before reaching the client.
POST https://api.dike.it.com/v1/reason
Authorization: Bearer dike_live_xxxxxxxx
Content-Type: application/jsonPlan Requirement
POST /v1/reason requires an active Pay As You Go or Enterprise plan. Calling on a Free tier returns 403 with code: plan_required.
Rendering diagram...
Request Parameters
{
"question": "ما هي التزامات المؤجر في صيانة العين المؤجرة وفقاً للقانون المصري؟",
"filters": {
"jurisdiction": "EG",
"status": ["in_force"]
},
"top_k": 12,
"stream": false,
"language": "ar"
}Body Schema
| Parameter | Type | Default | Constraints | Description |
|---|---|---|---|---|
question | string | Required | 5–2000 chars | The natural language legal question in Arabic or English. |
filters | object | null | Same schema as /v1/search | Optional filters (jurisdiction, doc_type, year_from, year_to, status). |
top_k | integer | 12 | 4–30 | Number of legal chunks retrieved into the reasoning context window. |
stream | boolean | false | true or false | When true, returns a Server-Sent Events (text/event-stream) stream. |
language | string | "ar" | "ar" or "en" | Language of the generated synthesis. |
Synchronous Code Examples
curl -X POST https://api.dike.it.com/v1/reason \
-H "Authorization: Bearer $DIKE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"question": "هل يجوز للمستأجر حبس الأجرة إذا امتنع المؤجر عن إجراء الترميمات الضرورية؟",
"filters": {"jurisdiction": "EG"},
"top_k": 12
}'import os
import httpx
client = httpx.Client(
base_url="https://api.dike.it.com",
headers={"Authorization": f"Bearer {os.getenv('DIKE_API_KEY')}"},
timeout=30.0,
)
response = client.post(
"/v1/reason",
json={
"question": "هل يجوز للمستأجر حبس الأجرة إذا امتنع المؤجر عن إجراء الترميمات الضرورية؟",
"filters": {"jurisdiction": "EG"},
"top_k": 12,
},
)
# Check for weak grounding header
is_weak = response.headers.get("X-Dike-Grounding") == "weak"
data = response.json()
print(f"Grounding Status: {'WEAK' if is_weak else 'STRONG'}")
print("Answer:\n", data["answer"])
print(f"Citations Verified: {len(data['citations'])}")const apiKey = process.env.DIKE_API_KEY;
async function askLegalQuestion() {
const res = await fetch('https://api.dike.it.com/v1/reason', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
question: 'هل يجوز للمستأجر حبس الأجرة إذا امتنع المؤجر عن إجراء الترميمات الضرورية؟',
filters: { jurisdiction: 'EG' },
top_k: 12,
}),
});
const isWeak = res.headers.get('X-Dike-Grounding') === 'weak';
const data = await res.json();
return { ...data, isWeakGrounding: isWeak };
}Streaming Protocol (stream: true)
When stream: true is passed, the connection switches to Content-Type: text/event-stream.
Stream Events Lifecycle
- Token Chunks (
message): Emits raw answer tokens. Token buffers prevent partial citation tags from splitting across chunk boundaries. - Citations Payload (
citations): Emits a final event containing all verified citation metadata and grounding stats.
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: {"token": "يلتزم "}
data: {"token": "المؤجر "}
data: {"token": "بإجراء الترميمات الضرورية [1] "}
event: citations
data: {"citations": [{"marker": 1, "canonical_id": "eg-leg-1948-131", "article_no": "567", "citation_string": "المادة 567 من القانون المدني", "snippet": "...", "verified": true}], "grounding": {"retrieved": 12, "used": 1, "dropped_unverified_refs": 0}}
data: [DONE]TypeScript SSE Streaming Client
async function streamReasoning(question: string) {
const response = await fetch('https://api.dike.it.com/v1/reason', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DIKE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ question, stream: true }),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (reader) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// Process SSE lines
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('data: ') && !line.includes('[DONE]')) {
const json = JSON.parse(line.slice(6));
if (json.token) process.stdout.write(json.token);
}
}
}
}Response Schema (Non-Streaming)
{
"answer": "وفقاً لأحكام القانون المدني المصري رقم 131 لسنة 1948، يلتزم المؤجر بصيانة العين المؤجرة وإجراء الترميمات الضرورية [1]. فإذا أخل المؤجر بذلك بعد إنذاره، يجوز للمستأجر استئذان القضاء لإجراء الترميمات وخصمها من الأجرة أو فسخ الإيجار [1].",
"citations": [
{
"marker": 1,
"canonical_id": "eg-leg-1948-131",
"article_no": "567",
"citation_string": "المادة 567 من القانون المدني رقم 131 لسنة 1948",
"snippet": "على المؤجر أن يتعهد العين المؤجرة بالصيانة لتبقى على الحالة التي سلمت بها...",
"verified": true
}
],
"grounding": {
"retrieved": 12,
"used": 1,
"dropped_unverified_refs": 0
},
"took_ms": 2910
}Error Codes
| Status | Code | Cause |
|---|---|---|
401 | unauthorized | Missing or invalid API key |
403 | plan_required | Attempted to call /v1/reason on a Free plan |
422 | validation_error | Missing question or parameter constraints violated |
429 | rate_limited | Exceeded 10 req/min limit on Pay As You Go |
503 | upstream_unavailable | Downstream LLM inference service temporary failure |