# Doubao Agent

XRToken exposes the Doubao Agent session API with both JSON and SSE streaming responses.

## Endpoint

`POST /v1/agent/chat/completions`

Compatibility aliases: `POST /v1/agent/chat/completion` and `POST /v1/agents/chat/completions`.

## Request

```json
{
  "bot_id": "your-agent-id",
  "agent_variant": "lite",
  "stream": false,
  "messages": [
    { "role": "user", "content": "What is the weather in Beijing today?" }
  ],
  "user_id": "user-123"
}
```

`bot_id` and `messages` are required. `bot_id` must be enabled for your account. `agent_variant` is optional and accepts `lite` or `pro`; when omitted, the Agent's configured default is used. `model` accepts `thinking`, `auto_thinking`, or `reasoning_search`.

### Request parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `bot_id` | string | yes | Agent identifier |
| `messages` | array | yes | Conversation messages with `system`, `user`, and `assistant` roles |
| `stream` | boolean | no | Enable SSE streaming; default `false` |
| `agent_variant` | string | no | `lite` or `pro` |
| `user_id` | string | no | Stable end-user identifier for session, memory, and personalization; not the XRToken account ID |
| `device_id` | string | no | Device identifier |
| `location_info` | object | no | Current location. For travel/weather send `longitude`, `latitude` (6 decimal places), `province`, `city`, `district`, and `town` (street). The playground pin reverse-geocodes the browser position into these fields |
| `navigation_info` | object | no | Navigation context |
| `knowledge` | string | no | Background context to inject for this request |
| `memory` | string | no | User profile or personalized memory |
| `model` | string | no | `thinking`, `auto_thinking`, or `reasoning_search` |
| `extension_options` | object | no | Advanced feature switches |

`user_id` should be a stable, non-sensitive business user identifier. It does not replace API-key authentication.

### Message content

Text, image URL, and public file URL content are supported:

```json
{
  "role": "user",
  "content": [
    { "type": "text", "text": "Summarize this file" },
    { "type": "file_url", "file_url": { "url": "https://example.com/a.pdf" } }
  ]
}
```

### `extension_options`

| Parameter | Type | Description |
| --- | --- | --- |
| `filter_emoji` | boolean | When `true`, filter emoji from model output |
| `enable_processing_state` | boolean | When `true`, output key Agent execution states; streaming only |
| `disable_source_type_douyin_video` | boolean | When `true`, disable the Douyin video source configured for the Agent |
| `disable_follow_up` | boolean | When `true`, disable configured follow-up questions |
| `disable_citation` | boolean | When `true`, disable citation markers |
| `disable_image_text_mix` | boolean | When `true`, disable image-text mixed output |
| `disable_baike_highlight` | boolean | When `true`, disable Baike highlighted terms |
| `disable_text_to_image` | boolean | When `true`, disable image search |
| `enable_search_lite` | boolean | When `true`, enable the faster search mode; quality may be lower |
| `browsing_mode` | number | Browsing mode: `1` automatic, `2` forced browsing, `3` browsing disabled. For text search, `2` uses at least one search source |
| `card_position` | string | Card placement: `first_frame` (default) or `meta_frame` |
| `enable_followup_in_response` | boolean | When `true`, enable an enhanced follow-up at the end of the answer |
| `disable_ecom_link` | boolean | When `true`, disable e-commerce intent and links in summaries/cards |
| `disable_video_text_mix` | boolean | When `true`, disable video-text mixed output |
| `learn_mode` | string | Homework Q&A add-on; after purchase, pass `auto_learning` so the system may enable the solving path. Not exposed on the playground |
| `reasoning_effort` | string | Reasoning length: `high`, `medium`, or `low`; ignored in automatic thinking mode |
| `sites` | string[] | Restrict search to up to 20 complete domains |
| `block_hosts` | string[] | Block up to 20 complete domains; takes priority over `sites` |
| `time_range` | string | Search time window, e.g. `1d` or `1w` |
| `search_auth_info_level` | number | Search authority filter: `0` unrestricted, `1` only highly authoritative sites |

Example (forced browsing with site filters):

```json
{
  "extension_options": {
    "browsing_mode": 2,
    "sites": ["gov.cn", "news.qq.com"],
    "block_hosts": ["example.com"],
    "disable_citation": false,
    "card_position": "meta_frame"
  }
}
```

Other request fields are forwarded as-is; availability depends on the configured Agent capabilities.

## Response

Non-streaming responses preserve the Agent JSON shape, including `choices`, `references`, `search_results`, `cards`, `follow_ups`, `thinking_references`, and `usage`. Streaming responses use `text/event-stream` with `data:{...}` frames and terminate with `data:[DONE]`.

## Companion APIs

Official companion APIs also use a `tr-` key. Volcengine AK/SK are never exposed. Opening remarks, opening questions, hot questions, and event logs usually have no token usage, so the gateway does not freeze balance.

The `/agent` experience page calls these endpoints. The Bot must be **Pro**, with toolkit, knowledge, Douyin, mixed media, highlights, follow-ups, citations, and cards enabled in the Volcengine console. There is no per-request "enable for the first time" API; disabled capabilities stay off even if the page toggle is on.

### List available bots

`GET /v1/agent/bots`

Returns enabled Agents the current key may use (gateway-local list, not a Volcengine API).

### Opening remark and questions

`POST /v1/agent/config`

```json
{ "bot_id": "your-agent-id" }
```

Proxies Volcengine `GetBotMeta` (`Version=2026-01-01`, `ServiceName=ask_echo`). Returns the console **opening remark** (`OpeningRemark`) and **opening questions** (`OpeningQuestions`). The experience page shows the remark as the agent's first greeting.

### Hot opening questions

`POST /v1/agent/opening-questions`

```json
{
  "bot_id": "your-agent-id",
  "user_id": "user-123",
  "count": 5
}
```

`bot_id` is required. `count` is 1–10; illegal values become 3. Proxies Volcengine `GetOpeningQuestion` for trending questions, not the console greeting.

### Event log

`POST /v1/agent/events`

```json
{
  "bot_id": "your-agent-id",
  "request_id": "upstream session id",
  "user_id": "user-123",
  "event_list": [
    { "event_name": "agent_like", "event_time": 1710000000 }
  ]
}
```

`bot_id` is used only for gateway ACL and is stripped before forwarding. `request_id` and `event_list` are required, max 20 events. Names include `agent_like`, `agent_copy`, `agent_follow_up`, `agent_reference`, and `agent_opening_question_click`. Proxies Volcengine `AgentEventLog`.

Homework grading, news feeds, custom usage reconciliation, and 180-day audit APIs are out of scope. Session `usage` comes from the ChatCompletion response.

## Related

Litigation / tax-risk lookup is a **different endpoint**: `POST /v1/agent/risk/chat/completions`, not this Doubao proxy. See [Risk Agent](/docs/agent-risk).
