DocsAPIQueries

Queries.

The synchronous query endpoint. Submit a question, get a citation-grade answer back, plus a timeline handle for the persistent run record.

§ 01Endpoint

POST/api/v1/query

Authenticates with a Bearer esk_ key (preferred) or the X-API-Key header. See Authentication for both formats.

§ 02Request

The body is a small JSON object. query is the question; metadata is an opaque object echoed back on the timeline for your own bookkeeping.

json
{
  "query": "Compare GDPR and CCPA on data subject deletion rights.",
  "metadata": {
    "user_id": "u_42",
    "trace_id": "abc-def-ghi"
  }
}

Parameters

ParamTypeRequiredDescription
querystringyesThe question to research. Plain text. Up to 4,000 characters. Be specific — the engine works best with concrete prompts.
metadataobjectnoFree-form JSON. Up to 8 KB. Echoed back on the run timeline. Use it to attach your own user id, trace id, request tags.

§ 03Response

A 200 response carries the full envelope. request_id is your handle for the run; answer and sources are the synthesized output; usage is the accounting; upstream is engine diagnostics.

FieldTypeDescription
request_idstringStable id for the run. Use to fetch the timeline at /api/v1/runs/{request_id}.
statusstringok on success, error on failure.
answerstringSynthesized answer text. May contain inline citation markers like [1], [2].
sourcesarraySource objects — title, url, domain, snippet, relevance, credibility.
usage.tokens_innumberTokens consumed on input across the full run.
usage.tokens_outnumberTokens generated on output across the full run.
usage.latency_msnumberWall-clock latency from request receipt to response dispatch.
errorsarray{ code, message } objects. Empty on success.
upstreamobjectEngine diagnostics — model, retries, partial failures.

Status codes

CodeMeaning
200Success. Envelope has status: "ok".
400Invalid body — missing query, malformed JSON, oversize input.
401Unauthorized — missing, malformed, revoked, or inactive key.
402Over quota — plan ceiling reached; upgrade or wait for the next period.
429Rate limited — too many requests in a short window. Back off and retry.
502Upstream engine error. Transient; retry with backoff.
504Upstream timeout. The engine took longer than 180s. Retry, or use the streaming endpoint for longer runs.

Timeouts

The synchronous endpoint has a 180-second hard timeout. Most queries complete in 10-30 seconds; complex multi-source synthesis can take longer. For runs that may exceed 180s, use streaming instead — the stream timeout is 300s and you see progress as it unfolds.

TipIf you find yourself routinely hitting 504s on the synchronous endpoint, switch to streaming. The events arrive incrementally and you can render partial state to your users while the full answer is still building.

§ 04Examples

curl

curl
curl https://api.essarion.com/api/v1/query \
  -H "Authorization: Bearer $ESSARION_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Compare GDPR and CCPA on data subject deletion rights.",
    "metadata": { "trace_id": "abc-123" }
  }'

Node — fetch

node
async function ask(question) {
  const res = await fetch("https://api.essarion.com/api/v1/query", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.ESSARION_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: question,
      metadata: { trace_id: crypto.randomUUID() },
    }),
  });

  if (!res.ok) {
    const body = await res.json().catch(() => ({}));
    throw new Error(`Essarion ${res.status}: ${body?.errors?.[0]?.code ?? "unknown"}`);
  }

  return res.json();
}

const result = await ask("Compare GDPR and CCPA on data subject deletion rights.");
console.log(result.answer);

Python — httpx

python
import os, uuid, httpx

def ask(question: str) -> dict:
    resp = httpx.post(
        "https://api.essarion.com/api/v1/query",
        headers={"Authorization": f"Bearer {os.environ['ESSARION_KEY']}"},
        json={
            "query": question,
            "metadata": {"trace_id": str(uuid.uuid4())},
        },
        timeout=200.0,
    )
    resp.raise_for_status()
    return resp.json()

result = ask("Compare GDPR and CCPA on data subject deletion rights.")
print(result["answer"])

§ 05Example response

An abbreviated 200 response — citation markers in answer, ranked sources with credibility scores, the run accounting, and engine diagnostics.

json
{
  "request_id": "req_01HXYZABC123",
  "status": "ok",
  "answer": "Both GDPR (Article 17) and CCPA (Section 1798.105) grant a right to deletion, but they differ in scope and exceptions [1][2]. Under GDPR the right applies to any data controller processing personal data of EU residents, while CCPA applies to for-profit businesses meeting specific thresholds operating in California [3]...",
  "sources": [
    {
      "title": "Right to erasure (Article 17)",
      "url": "https://gdpr-info.eu/art-17-gdpr/",
      "domain": "gdpr-info.eu",
      "snippet": "The data subject shall have the right to obtain from the controller the erasure of personal data...",
      "relevance": 0.96,
      "credibility": 0.92
    },
    {
      "title": "California Consumer Privacy Act — Section 1798.105",
      "url": "https://leginfo.legislature.ca.gov/...",
      "domain": "leginfo.legislature.ca.gov",
      "snippet": "A consumer shall have the right to request that a business delete...",
      "relevance": 0.95,
      "credibility": 0.95
    }
  ],
  "usage": {
    "tokens_in": 612,
    "tokens_out": 2240,
    "latency_ms": 18420
  },
  "errors": [],
  "upstream": {
    "model": "essarion-research-1",
    "retries": 0,
    "sources_discovered": 38,
    "sources_analyzed": 12
  }
}