Run timelines.
Every query gets a request_id. Use it to fetch the full reasoning trail — every step, every source, every citation, persisted.
§ 01Endpoint
Authenticates with either a session cookie or an esk_ API key. The gateway verifies that the requested run belongs to the calling account; cross-account reads return 404, not 403, so you cannot probe for the existence of other accounts' run ids.
§ 02Response shape
The response is a single timeline object. It carries the original query, the request envelope, an ordered list of steps, the reasoning chunks, and the ranked sources at every stage.
| Field | Type | Description |
|---|---|---|
| request_id | string | The id you used to fetch this timeline. |
| query | string | The original question text. |
| metadata | object | The metadata you passed in on the original request, echoed verbatim. |
| status | string | ok, error, or running if you fetch while a stream is still in progress. |
| steps | array | Ordered list of step objects — see below. |
| reasoning_chunks | array | Ordered text fragments emitted during synthesis, with step_id back-references. |
| sources | array | All sources surfaced during the run, with stage, scores, and citation flags. |
| answer | string | The final synthesized answer (empty if status is not ok). |
| usage | object | Token and latency totals. |
| created_at | string | ISO-8601 timestamp of when the run started. |
| completed_at | string | ISO-8601 timestamp of when the final event fired (null if still running). |
Step shape
Each entry in steps describes one phase of the run — planning, search, scraping, scoring, analysis, synthesis. Steps are ordered by started_at.
| Field | Type | Description |
|---|---|---|
| id | string | Step id. Reasoning chunks reference this. |
| phase | string | One of plan, search, scrape, score, analyze, synthesize. |
| label | string | Human-readable summary of what this step did. |
| status | string | ok, error, or skipped. |
| started_at | string | ISO-8601 start timestamp. |
| completed_at | string | ISO-8601 end timestamp. |
| metadata | object | Phase-specific data — sub-query text for plan, hit count for search, byte counts for scrape. |
Source shape
| Field | Type | Description |
|---|---|---|
| stage | string | discovered, scraped, or analyzed. |
| title | string | Page title. |
| url | string | Canonical URL. |
| domain | string | Hostname. |
| snippet | string | Excerpt used during analysis. |
| scores | object | relevance and credibility, each 0-1. |
| citations | array | Inline citation markers in the answer that reference this source — [1], [2], etc. |
§ 03Status codes
| Code | Meaning |
|---|---|
| 200 | Timeline returned. |
| 401 | Unauthenticated. No valid session cookie or esk_ key. |
| 404 | Either the request_id does not exist, or it does not belong to the caller. We do not differentiate; the response body is identical in both cases. |
§ 04Examples
curl
curl https://api.essarion.com/api/v1/runs/req_01HXYZABC123 \
-H "Authorization: Bearer $ESSARION_KEY"
Node — fetch
async function getTimeline(requestId) {
const res = await fetch(
`https://api.essarion.com/api/v1/runs/${requestId}`,
{ headers: { "Authorization": `Bearer ${process.env.ESSARION_KEY}` } },
);
if (res.status === 404) throw new Error("Run not found");
if (!res.ok) throw new Error(`Essarion ${res.status}`);
const timeline = await res.json();
for (const step of timeline.steps) {
console.log(`${step.phase} · ${step.label} · ${step.status}`);
}
return timeline;
}
§ 05Example response
An abbreviated timeline for a two-source run. Steps walk through plan, search, scrape, analyze, synthesize. Reasoning chunks reference step ids. Sources carry their stage and scores.
{
"request_id": "req_01HXYZABC123",
"query": "Compare GDPR and CCPA on data subject deletion rights.",
"metadata": { "trace_id": "abc-123" },
"status": "ok",
"created_at": "2026-05-01T14:22:08Z",
"completed_at": "2026-05-01T14:22:36Z",
"steps": [
{
"id": "step_01",
"phase": "plan",
"label": "Decomposed into 3 sub-queries",
"status": "ok",
"started_at": "2026-05-01T14:22:08Z",
"completed_at": "2026-05-01T14:22:09Z",
"metadata": { "subqueries": ["GDPR Article 17", "CCPA Section 1798.105", "comparison"] }
},
{
"id": "step_02",
"phase": "search",
"label": "38 candidate sources",
"status": "ok",
"started_at": "2026-05-01T14:22:09Z",
"completed_at": "2026-05-01T14:22:14Z",
"metadata": { "hits": 38 }
},
{
"id": "step_05",
"phase": "synthesize",
"label": "Wrote final answer",
"status": "ok",
"started_at": "2026-05-01T14:22:30Z",
"completed_at": "2026-05-01T14:22:36Z",
"metadata": { "tokens_out": 2240 }
}
],
"reasoning_chunks": [
{ "step_id": "step_05", "text": "Both regimes provide deletion, but the trigger conditions differ..." }
],
"sources": [
{
"stage": "analyzed",
"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...",
"scores": { "relevance": 0.96, "credibility": 0.92 },
"citations": ["[1]"]
}
],
"answer": "Both GDPR (Article 17) and CCPA (Section 1798.105) grant a right to deletion...",
"usage": { "tokens_in": 612, "tokens_out": 2240, "latency_ms": 28000 }
}