For the complete documentation index, see llms.txt. This page is also available as Markdown.
Your first request
A slower walkthrough than quickstart, explaining every part of the call. Use this page if the quickstart worked but you want to know why.
Anatomy of a request
| Part | Value | Why |
|---|---|---|
| Base URL | https://api.scispace.com/v1 | |
| Auth header | Authorization: Bearer … | authentication |
| Version header | SciSpace-Version: 2026-08-01 | versioning |
| Idempotency header | Idempotency-Key: <uuid> | safe retries on metered calls |
| Body | JSON |
Anatomy of a response
Every object comes back in the same envelope: an object type, a prefixed id, and created_at.
{
"object": "search",
"id": "srch_9dm2pq4x1a",
"created_at": "2026-08-11T09:14:22Z",
"status": "succeeded",
"depth": "standard",
"paper_count": 20,
"credits_cost": 5
}Asynchronous creates return 202 Accepted, not 200, and the body has no result yet — only a
handle to poll or wait on:
{
"object": "search",
"id": "srch_9dm2pq4x1a",
"created_at": "2026-08-11T09:14:22Z",
"status": "queued",
"answer": null,
"completed_at": null,
"error": null
}status moves queued → running → succeeded | failed | canceled. Only succeeded populates the
result; failed populates error. See Job.
Response headers
These come back on every response, including errors. This is the only page that explains them — reference pages link here.
| Header | Example | What to do with it |
|---|---|---|
X-Request-Id | req_5a0c1e8b7d | Log it. Quote it in every support ticket; it is how we find your call. |
X-RateLimit-Limit | 60 | Requests allowed in the current window, for this key. |
X-RateLimit-Remaining | 57 | Requests left. Slow down as it approaches zero. |
X-RateLimit-Reset | 1786518900 | Unix seconds when the window resets. |
X-Credits-Cost | 5 | Credits this call consumed. 0 on reads and on errors. |
X-Credits-Remaining | 9,412 | Balance after the call. Alert on it; do not wait for a 402. |
On 429, Retry-After is also sent, in seconds. Honour it rather than guessing — see
errors-and-retries and rate-limits.
Making it async-safe
Searches, chats, documents, extractions and topic searches are asynchronous. Three ways to wait, in descending order of preference.
Webhooks — best for servers. Register once, get pushed the terminal state. No polling, no timeout to tune.
curl https://api.scispace.com/v1/webhook_endpoints \
-H "Authorization: Bearer $SCISPACE_API_KEY" \
-H "SciSpace-Version: 2026-08-01" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/scispace",
"enabled_events": ["search.succeeded", "search.failed"]
}'See webhook-endpoints for signature verification — verify before you trust the payload.
.wait() — best for scripts. The SDKs poll for you with the right backoff.
search = client.searches.create(
query="How does climate change affect biodiversity?",
depth="standard",
).wait(timeout=60)Polling — when you have neither. Fetch the resource itself; there is no separate status endpoint. Start at 1s, double to a 30s ceiling, and give up at the depth's p95 latency plus headroom.
delay=1
while :; do
status=$(curl -sS "https://api.scispace.com/v1/searches/srch_9dm2pq4x1a" \
-H "Authorization: Bearer $SCISPACE_API_KEY" \
-H "SciSpace-Version: 2026-08-01" | jq -r .status)
[ "$status" = "succeeded" ] && break
[ "$status" = "failed" ] && exit 1
sleep "$delay"
delay=$(( delay * 2 > 30 ? 30 : delay * 2 ))
doneDo not poll in a tight loop
Every poll is a request against your rate limit. Retrieves cost no credits, but a 100ms loop will
exhaust the limit long before a deep_review finishes.
Related
Last updated