--- title: Interacting with Agents via API description: Learn how to programmatically interact with DocsGPT Agents using the streaming and non-streaming API endpoints. --- import { Callout, Tabs } from 'nextra/components'; # Interacting with Agents via API DocsGPT Agents can be accessed programmatically through API endpoints. This page covers: - Non-streaming answers (`/api/answer`) - Streaming answers over SSE (`/stream`) - File/image attachments (`/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`. ## Base URL For DocsGPT Cloud, use `https://gptcloud.arc53.com` as the base URL. - Local: `http://localhost:7091` - Cloud: `https://gptcloud.arc53.com` ## How Request Resolution Works DocsGPT resolves your request in this order: 1. If `api_key` is provided, DocsGPT loads the mapped agent and executes with that config. 2. If `agent_id` is provided (typically with JWT auth), DocsGPT loads that agent if allowed. 3. If neither is provided, DocsGPT uses request-level fields (`prompt_id`, `active_docs`, `retriever`, etc.). Authentication: - Agent API-key flow: include `api_key` in JSON/form payload. - JWT flow (if auth enabled): include `Authorization: Bearer `. ## Endpoints - `POST /api/answer` (non-streaming) - `POST /stream` (SSE streaming) - `POST /api/store_attachment` (multipart upload) - `GET /api/task_status?task_id=...` (Celery task polling) ## Request Parameters 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. | ## Non-Streaming API (`/api/answer`) `/api/answer` waits for completion and returns one JSON response. `attachments` are currently handled through `/stream`. For file/image-attached queries, use the streaming endpoint. Response fields: - `conversation_id` - `answer` - `sources` - `tool_calls` - `thought` - Optional structured output metadata (`structured`, `schema`) when enabled ### Examples ```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"}' ``` ```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) ``` ```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(); ``` --- ## Streaming API (`/stream`) `/stream` returns a Server-Sent Events (SSE) stream so you can render output token-by-token. ### SSE Event Types Each `data:` frame is JSON with `type`: - `answer`: incremental answer chunk - `source`: source list/chunks - `tool_calls`: tool invocation results/metadata - `thought`: reasoning/thought chunk (agent dependent) - `structured_answer`: final structured payload (when schema mode is active) - `id`: final conversation ID - `error`: error message - `end`: stream is complete ### Examples ```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"}' ``` ```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 ``` ```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(); ``` --- ## Attachments API (Including Images) To attach an image (or other file) to a query: 1. Upload file(s) to `/api/store_attachment` (multipart/form-data). 2. Poll `/api/task_status` until `status=SUCCESS`. 3. Read `result.attachment_id` from task result. 4. Send that ID in `/stream` as `attachments: ["..."]`. Attachments are processed asynchronously. Do not call `/stream` with an attachment until its task has finished with `SUCCESS`. ### Step 1: Upload Attachment `POST /api/store_attachment` - Content type: `multipart/form-data` - Form fields: - `file` (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): ```bash 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): ```json { "success": true, "task_id": "34f1cb56-7c7f-4d5f-a973-4ea7e65f7a10", "message": "File uploaded successfully. Processing started." } ``` ### Step 2: Poll Task Status ```bash curl "http://localhost:7091/api/task_status?task_id=34f1cb56-7c7f-4d5f-a973-4ea7e65f7a10" ``` When complete: ```json { "status": "SUCCESS", "result": { "attachment_id": "67b4f8f2618dc9f19384a9e1", "filename": "image.png", "mime_type": "image/png" } } ``` ### Step 3: Attach to `/stream` Request Use the `attachment_id` in `attachments`. ```bash 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/Attachment Behavior Notes - Typical image MIME types supported for native vision flows: `image/png`, `image/jpeg`, `image/jpg`, `image/webp`, `image/gif`. - If the selected model/provider does not support a file type natively, DocsGPT falls back to parsed text content. - For providers that support images but not native PDF file attachments, DocsGPT can convert PDF pages to images (synthetic PDF support). - Attachments are user-scoped. Upload and query must be done under the same user context (same API key owner or same JWT user).