docs/content/Agents/api.mdx
import { Callout, Tabs } from 'nextra/components';
DocsGPT Agents can be accessed programmatically through API endpoints. This page covers:
/api/answer)/stream)/api/store_attachment + /api/task_status + /stream)When you use an agent api_key, DocsGPT loads that agent's configuration automatically (prompt, tools, sources, default model). You usually only need to send question and api_key.
http://localhost:7091https://gptcloud.arc53.comDocsGPT resolves your request in this order:
api_key is provided, DocsGPT loads the mapped agent and executes with that config.agent_id is provided (typically with JWT auth), DocsGPT loads that agent if allowed.prompt_id, active_docs, retriever, etc.).Authentication:
api_key in JSON/form payload.Authorization: Bearer <token>.POST /api/answer (non-streaming)POST /stream (SSE streaming)POST /api/store_attachment (multipart upload)GET /api/task_status?task_id=... (Celery task polling)Common request body fields:
| Field | Type | Required | Applies to | Notes |
|---|---|---|---|---|
question | string | Yes | /api/answer, /stream | User query. |
api_key | string | Usually | /api/answer, /stream | Recommended for agent API use. Loads agent config from key. |
conversation_id | string | No | /api/answer, /stream | Continue an existing conversation. |
history | string (JSON-encoded array) | No | /api/answer, /stream | Used for new conversations. Format: [{\"prompt\":\"...\",\"response\":\"...\"}]. |
model_id | string | No | /api/answer, /stream | Override model for this request. |
save_conversation | boolean | No | /api/answer, /stream | Default true. If false, no conversation is persisted. |
passthrough | object | No | /api/answer, /stream | Dynamic values injected into prompt templates. |
prompt_id | string | No | /api/answer, /stream | Ignored when api_key already defines prompt. |
active_docs | string or string[] | No | /api/answer, /stream | Overrides active docs when not using key-owned source config. |
retriever | string | No | /api/answer, /stream | Retriever type (for example classic). |
chunks | number | No | /api/answer, /stream | Retrieval chunk count, default 2. |
isNoneDoc | boolean | No | /api/answer, /stream | Skip document retrieval. |
agent_id | string | No | /api/answer, /stream | Alternative to api_key when using authenticated user context. |
Streaming-only fields:
| Field | Type | Required | Notes |
|---|---|---|---|
attachments | string[] | No | List of attachment IDs from /api/task_status success result. |
index | number | No | Update an existing query index. If provided, conversation_id is required. |
/api/answer)/api/answer waits for completion and returns one JSON response.
Response fields:
conversation_idanswersourcestool_callsthoughtstructured, schema) when enabled<Tabs items={['cURL', 'Python', 'JavaScript']}>
<Tabs.Tab>
bash curl -X POST http://localhost:7091/api/answer \ -H "Content-Type: application/json" \ -d '{"question":"your question here","api_key":"your_agent_api_key"}'
</Tabs.Tab>
<Tabs.Tab>
```python
import requests
API_URL = "http://localhost:7091/api/answer"
API_KEY = "your_agent_api_key"
QUESTION = "your question here"
response = requests.post(
API_URL,
json={"question": QUESTION, "api_key": API_KEY}
)
if response.status_code == 200:
print(response.json())
else:
print(f"Error: {response.status_code}")
print(response.text)
```
</Tabs.Tab> <Tabs.Tab> ```javascript const apiUrl = 'http://localhost:7091/api/answer'; const apiKey = 'your_agent_api_key'; const question = 'your question here';
async function getAnswer() {
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ question, api_key: apiKey }),
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Failed to fetch answer:", error);
}
}
getAnswer();
```
</Tabs.Tab> </Tabs>
/stream)/stream returns a Server-Sent Events (SSE) stream so you can render output token-by-token.
Each data: frame is JSON with type:
answer: incremental answer chunksource: source list/chunkstool_calls: tool invocation results/metadatathought: reasoning/thought chunk (agent dependent)structured_answer: final structured payload (when schema mode is active)id: final conversation IDerror: error messageend: stream is complete<Tabs items={['cURL', 'Python', 'JavaScript']}>
<Tabs.Tab>
bash curl -X POST http://localhost:7091/stream \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{"question":"your question here","api_key":"your_agent_api_key"}'
</Tabs.Tab>
<Tabs.Tab>
```python
import requests
import json
API_URL = "http://localhost:7091/stream"
payload = {
"question": "your question here",
"api_key": "your_agent_api_key"
}
with requests.post(API_URL, json=payload, stream=True) as r:
for line in r.iter_lines():
if line:
decoded_line = line.decode('utf-8')
if decoded_line.startswith('data: '):
try:
data = json.loads(decoded_line[6:])
print(data)
except json.JSONDecodeError:
pass
```
</Tabs.Tab> <Tabs.Tab> ```javascript const apiUrl = 'http://localhost:7091/stream'; const apiKey = 'your_agent_api_key'; const question = 'your question here';
async function getStream() {
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'text/event-stream'
},
body: JSON.stringify({ question, api_key: apiKey }),
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
// Note: This parsing method assumes each chunk contains whole lines.
// For a more robust production implementation, buffer the chunks
// and process them line by line.
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.substring(6));
console.log(data);
} catch (e) {
console.error("Failed to parse JSON from SSE event:", e);
}
}
}
}
} catch (error) {
console.error("Failed to fetch stream:", error);
}
}
getStream();
```
</Tabs.Tab> </Tabs>
To attach an image (or other file) to a query:
/api/store_attachment (multipart/form-data)./api/task_status until status=SUCCESS.result.attachment_id from task result./stream as attachments: ["..."].POST /api/store_attachment
multipart/form-datafile (required, can be repeated for multi-file upload)api_key (optional if JWT is present; useful for API-key-only flows)Example upload (single image):
curl -X POST http://localhost:7091/api/store_attachment \
-F "file=@/absolute/path/to/image.png" \
-F "api_key=your_agent_api_key"
Possible response (single-file upload):
{
"success": true,
"task_id": "34f1cb56-7c7f-4d5f-a973-4ea7e65f7a10",
"message": "File uploaded successfully. Processing started."
}
curl "http://localhost:7091/api/task_status?task_id=34f1cb56-7c7f-4d5f-a973-4ea7e65f7a10"
When complete:
{
"status": "SUCCESS",
"result": {
"attachment_id": "67b4f8f2618dc9f19384a9e1",
"filename": "image.png",
"mime_type": "image/png"
}
}
/stream RequestUse the attachment_id in attachments.
curl -X POST http://localhost:7091/stream \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"question": "Describe this image",
"api_key": "your_agent_api_key",
"attachments": ["67b4f8f2618dc9f19384a9e1"]
}'
image/png, image/jpeg, image/jpg, image/webp, image/gif.