Research
Research is a deep-research agent over the same corpus Search reads. Three nouns: a session is a conversation; a turn is one question and the background run answering it (minutes, not seconds — it keeps running if you disconnect); a report is the deliverable, an answer with numbered citations, readable forever and free to re-read.
Start a turn
curl -s -X POST https://api.ariselabs-search-api.com/v1/research/sessions \
-H "Authorization: Bearer $ARISELABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "TSMC 2025 capex vs guidance"}'
# → 202 {"session_id": "…", "turn_id": "…", "status": "queued", "mode": "new_turn"}Optional fields: as_of anchors every retrieval to that
instant for the whole session; effort sets the effort level supported by your deployment.
Posting another question to
POST /v1/research/sessions/{id}/turns while a turn is running
steers the running turn instead of starting a new one.
Follow progress, read the report
# live progress (SSE; free): heartbeats every 10s, closed after ≤15 min —
# each frame carries id <session>:<seq>; resume with ?since_seq= to lose nothing
curl -N https://api.ariselabs-search-api.com/v1/research/sessions/$SESSION/events \
-H "Authorization: Bearer $ARISELABS_API_KEY"
# or just poll the report — while the turn runs this answers
# 409 {"error":{"code":"report_not_ready"}}; 200 = the delivered report
curl -s https://api.ariselabs-search-api.com/v1/research/sessions/$SESSION \
-H "Authorization: Bearer $ARISELABS_API_KEY"import httpx, os, time
H = {"Authorization": f"Bearer {os.environ['ARISELABS_API_KEY']}"}
BASE = "https://api.ariselabs-search-api.com"
r = httpx.post(f"{BASE}/v1/research/sessions",
headers=H, json={"query": "TSMC 2025 capex vs guidance"}).json()
sid = r["session_id"]
while True: # while the turn runs, the GET answers 409 report_not_ready
r = httpx.get(f"{BASE}/v1/research/sessions/{sid}", headers=H)
if r.status_code == 200:
report = r.json()
break
if r.json().get("error", {}).get("code") != "report_not_ready":
raise SystemExit(r.text)
time.sleep(10)
print(report["answer"])
for cite in report["citations"]:
print(f"[{cite['id']}]", cite.get("title"), cite.get("url"))Disconnecting from the event stream never cancels the run — attaching
is a read-only window. POST …/cancel stops the running turn
(work already done stays; the session stays usable).
Cost & limits
- A turn bills by actual token usage, capped at
5,000 credits ($5): the cap is reserved when the turn
starts, the difference refunded at delivery — the report's
usage.creditsis the real bill. Reading, listing, streaming and cancelling are free. 402 quota_exhausted— insufficient credits; add credit in the console.409 report_not_ready— the turn is still running.concurrency_limit_exceeded— too many turns at once; only a turn finishing orcancelfrees a slot.- Starting turns is limited to one every 2 s per key — an anti-double-click interval, not a quota. The only volume limit is the wallet.