For the complete documentation index, see llms.txt. This page is also available as Markdown.
Chats
Ask questions about a fixed set of documents and papers, and get answers with page-level citations.
When to use
The caller already knows which sources matter
You want a conversation with follow-ups
You need to stream an answer into a UI
When not to use
You do not know which papers matter yet → searches
One-shot structured fields across many PDFs → extractions
Endpoints
| Method | Path | Scope | Credits | Description |
|---|---|---|---|---|
| POST | /v1/chats | chats:write | 0 | Create, scoped to documents/papers |
| GET | /v1/chats/{id} | chats:read | 0 | Retrieve |
| POST | /v1/chats/{id}/messages | chats:write | 2 / 6 / 20 by depth | Ask a question; supports stream |
| GET | /v1/chats/{id}/messages | chats:read | 0 | List turns |
Parameters — create a chat
| Parameter | Type | Required | Description |
|---|---|---|---|
document_ids | string[] | one of | Your uploaded documents |
paper_ids | string[] | one of | Corpus papers |
depth | enum | no | Default for messages in this chat |
language | string | no | Answer language |
Parameters — send a message
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | yes | The question |
stream | boolean | no | SSE streaming, default false |
depth | enum | no | Overrides the chat default |
answer_format | enum | no | bulleted, paragraph |
Streaming
Set "stream": true and the response is text/event-stream. Events arrive in a fixed order:
message.delta repeatedly, then citation.added as sources resolve, then one message.completed.
curl -N https://api.scispace.com/v1/chats/chat_1r8eaidwoq/messages \
-H "Authorization: Bearer $SCISPACE_API_KEY" \
-H "SciSpace-Version: 2026-08-01" \
-H "Content-Type: application/json" \
-d '{"content":"How many layers does the encoder use?","stream":true}'event: message.delta
data: {"id":"msg_k7hcnivfll","delta":"The encoder and decoder each use "}
event: message.delta
data: {"id":"msg_k7hcnivfll","delta":"six identical layers [1]."}
event: citation.added
data: {"index":1,"quote":"The encoder is composed of a stack of N = 6 identical layers.","source":{"type":"document","id":"doc_8ba2f01c47"},"locations":[{"page":7,"bbox":{"x":0.252,"y":0.426,"width":0.495,"height":0.041}}]}
event: message.completed
data: {"id":"msg_k7hcnivfll","credits_cost":2,"unsourced_claim_count":0}Citations arrive after the text that references them, so render [n] markers as inert until the
matching citation.added lands. The SDKs expose the same stream as an iterator:
with client.chats.messages.stream(
chat_id="chat_1r8eaidwoq",
content="How many layers does the encoder use?",
) as stream:
for event in stream:
if event.type == "message.delta":
print(event.delta, end="", flush=True)
elif event.type == "citation.added":
print(f"\n[{event.index}] p.{event.locations[0].page}")
message = stream.get_final_message()A dropped connection still costs credits
The message is billed once generation starts. Reconnecting does not resume the stream — retrieve the message by id instead.
Response
{
"object": "message",
"id": "msg_k7hcnivfll",
"chat_id": "chat_1r8eaidwoq",
"role": "assistant",
"content": "The encoder and decoder each use six identical layers [1], and the model reaches 28.4 BLEU on WMT 2014 English-to-German [2].",
"citations": [
{
"index": 1,
"quote": "The encoder is composed of a stack of N = 6 identical layers.",
"source": {
"type": "document",
"id": "doc_8ba2f01c47",
"title": "Attention is all you need.pdf"
},
"locations": [
{
"page": 7,
"bbox": { "x": 0.252, "y": 0.426, "width": 0.495, "height": 0.041 }
}
]
}
…
],
"unsourced_claim_count": 0,
"credits_cost": 2,
"created_at": "2026-08-11T09:31:07Z"
}| Field | Type | Description |
|---|---|---|
role | enum | user or assistant |
content | string | The reply, carrying [n] markers keyed to citations[].index |
citations[].quote | string | The source span, verbatim. Use it to sanity-check the claim |
citations[].source.type | enum | document for your uploads, paper for corpus items |
citations[].locations[].page | integer | 1-indexed |
citations[].locations[].bbox | object | x, y, width, height as fractions of the page, origin top-left |
unsourced_claim_count | integer | Sentences with no citation. Surface it rather than hiding it |
A citation can carry more than one location when the claim spans a page break. Render every one.
bbox values are fractions, not pixels
Multiply by your rendered page size. citation-highlights shows the overlay maths against this exact citation.
Errors
| Status | code | When |
|---|---|---|
| 400 | no_sources | neither document_ids nor paper_ids given |
| 409 | document_not_ready | a document is still parsing |
| 413 | too_many_sources | more than 50 documents and papers combined |
Related
chat · message · citation · grounded-answers
Last updated