---
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 a dedicated API, allowing you to integrate their specialized capabilities into your own applications, scripts, and workflows. This guide covers the two primary methods for interacting with an agent: the streaming API for real-time responses and the non-streaming API for a single, consolidated answer.

When you use an API key generated for a specific agent, you do not need to pass `prompt`, `tools` etc. The agent's configuration (including its prompt, selected tools, and knowledge sources) is already associated with its unique API key. 

### API Endpoints

- **Non-Streaming:** `http://localhost:7091/api/answer`
- **Streaming:** `http://localhost:7091/stream`

<Callout type="info">
For DocsGPT Cloud, use `https://gptcloud.arc53.com/` as the base URL.
</Callout>

For more technical details, you can explore the API swagger documentation available for the cloud version or your local instance.

---

## Non-Streaming API (`/api/answer`)

This is a standard synchronous endpoint. It waits for the agent to fully process the request and returns a single JSON object with the complete answer. This is the simplest method and is ideal for backend processes where a real-time feed is not required.

### Request

-   **Endpoint:** `/api/answer`
-   **Method:** `POST`
-   **Payload:**
    -   `question` (string, required): The user's query or input for the agent.
    -   `api_key` (string, required): The unique API key for the agent you wish to interact with.
    -   `history` (string, optional): A JSON string representing the conversation history, e.g., `[{\"prompt\": \"first question\", \"answer\": \"first answer\"}]`.

### Response

A single JSON object containing:
-   `answer`: The complete, final answer from the agent.
-   `sources`: A list of sources the agent consulted.
-   `conversation_id`: The unique ID for the interaction.

### Examples

<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>

---

## Streaming API (`/stream`)

The `/stream` endpoint uses Server-Sent Events (SSE) to push data in real-time. This is ideal for applications where you want to display the response as it's being generated, such as in a live chatbot interface.

### Request

-   **Endpoint:** `/stream`
-   **Method:** `POST`
-   **Payload:** Same as the non-streaming API.

### Response (SSE Stream)

The stream consists of multiple `data:` events, each containing a JSON object. Your client should listen for these events and process them based on their `type`.

**Event Types:**
-   `answer`: A chunk of the agent's final answer.
-   `source`: A document or source used by the agent.
-   `thought`: A reasoning step from the agent (for ReAct agents).
-   `id`: The unique `conversation_id` for the interaction.
-   `error`: An error message.
-   `end`: A final message indicating the stream has concluded.

### Examples

<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'
        },
        // Corrected line: 'apiKey' is changed to 'api_key'
        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>
