General Conventions

This article describes the general calling conventions for the DolphinX API, providing a unified set of rules for protocols, authentication, errors, pagination, and stream processing in application-layer implementations.

1. Request Format

This section describes the request format for the HTTP API. The DolphinX API also supports WebSocket calls. For field mapping rules between HTTP and WebSocket, see WebSocket Protocol.

By default, the HTTP API uses JSON as the request and response format. The client should construct requests according to the following conventions:

  • Content-Type: application/json
  • Common request headers:
    • x-agent-id: Optional. Specifies agentId, equivalent to agentId in the request body or query parameters.
    • x-session-id: Optional. Specifies sessionId.

2. Authentication and Permissions

The DolphinX API reuses the DolphinDB login session and current user identity. HTTP calls typically obtain a session or token through the DolphinDB login API (/api/login) first. WebSocket connections can include Authorization: Bearer during the handshake. The server uses the current user from the authentication context as userId. Developers must not pass userId in the payload to impersonate another identity. If you don't have the necessary permissions, the API returns BUS_PERMISSION_DENIED. If you are not logged in or the login session has expired, it returns BUS_UNAUTHENTICATED.

Common permissions include:

Permission Description
AGENT_INVOKE Allows calling APIs for a specified ACTIVE agent, including /session/create, /chat/completions, workspace/*, skill/*, /network/fetch, and /mcp/tools/call, among others.
AGENT_ADMIN Administrative permission. Allows configuring agents, permissions, LLMs, skills, MCP servers, memory, and related resources.
DolphinDB admin A built-in system-level administrator in DolphinDB with the ability to initialize built-in resources and grant global permissions.

Obtain the DolphinDB login token

curl -sS -X POST "http://localhost:8848/api/login" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"username":"admin","password":"your-password"}'

The response is as follows. The DolphinDB login token is stored in the result field. Note that the result field is a string array. To retrieve the token, use result[0].

{
  "session":"8351577110388618226",
  "user":"admin",
  "code":0,
  "message":"",
  "result":["xxx"]
}

3. Response Format

Non-streaming responses use a standard envelope structure. An envelope is a JSON object that wraps the data field, which contains the business data. To avoid repeating common outer fields, response examples in later articles show only the content of the data field. When calling an API, you receive the complete envelope and must retrieve the business data from the data field.

Envelope structure:

{
 "type": "RESPONSE",
 "msgId": "...",
 "correlationId": "<requestId>",
 "action": "<action>",
 "agentId": "<agentId>",
 "sessionId": "<sessionId>",
 "data": { ... },
 "headers": { "...": "..." }
}
  • type: the return type.
  • msgId: the message ID generated by the server.
  • correlationId: used to correlate requests and responses. If the request does not provide x-request-id or a WebSocket requestId, the server generates one automatically.
  • action: the called API.
  • agentId: the agent ID.
  • sessionId: the session ID.
  • data: the business data.
  • headers: business metadata fields within the envelope, not HTTP response headers. Returned only when the server-side envelope headers are not empty.

A response may include compatibility, diagnostic, or internal fields not listed in this article. These fields are not part of the stable public contract, and developers should not rely on them.

The following is an example error response. For detailed error code descriptions, see Error Codes.

{
 "type": "ERROR",
 "msgId": "...",
 "correlationId": "<requestId>",
 "action": "<action>",
 "agentId": "<agentId>",
 "sessionId": "<sessionId>",
 "error": {
 "code": "<BusErrorCode>",
 "message": "<error message>",
 "reason": "<optional, reason for the error>",
 "providerStatus": "<optional, HTTP status code from LLM provider>",
 "providerCode": "<optional, error code from LLM provider>",
 "retryable": "<optional, true|false>"
 },
 "headers": {
 "busErrorCode": "<BusErrorCode>",
 "httpStatus": "<HTTP status code>",
 "llmProviderStatus": "<optional, HTTP status code from LLM provider>",
 "providerCode": "<optional, error code from LLM provider>",
 "retryable": "<optional, true|false>"
 }
}

4. Pagination Parameters

All list-related APIs support the following parameters:

Parameters Type Required Description
offset int No Skips the first offset records. The value must be a non-negative integer. The default value is 0.
limit int No The maximum number of records to return. The value must be a non-negative integer. A value of 0 indicates that an empty list is returned. The default value is 100.

Pagination parameters can be passed as URL query parameters or in the JSON request body.

5. Streaming Responses (HTTP SSE/WebSocket)

For HTTP APIs that support streaming responses, the stream request parameter controls how the response is returned:

  • stream=true (default): The response is returned as Server-Sent Events (SSE), so the server sends content as it is generated.
  • stream=false: The response is returned as an envelope after the server has generated all content.

For WebSocket calls, specify this parameter in payload.stream in the request frame.

HTTP SSE and WebSocket use the same set of envelope types; only the outer transport format differs. A typical event sequence is as follows:

[Optional EVENT ...]
↓
STREAM_START
↓
[STREAM_CHUNK / STREAM_REASONING / EVENT ...]
↓
STREAM_END or STREAM_ERROR

5.1 HTTP SSE

SSE response headers:

Content-Type: text/event-stream; charset=UTF-8
Cache-Control: no-cache
Connection: keep-alive
X-Agent-Bus-Streaming: true

The data field of each SSE event is a complete envelope, and type indicates the current stage. First, frame the stream by the SSE event, then parse the JSON in the data field. Do not concatenate multiple chunks and parse them as a single JSON object.

For HTTP SSE clients, chunk/reasoning_delta is intended only for real-time display. Near the end of the stream, STREAM_END.data in stream_end contains the complete response result. You must use the response result for business processing instead of concatenating chunks manually.

SSE Event Envelope Type Description
event EVENT Business process events, such as context compression progress.
stream_start STREAM_START The streaming request has started.
chunk STREAM_CHUNK Message body or structured delta.
reasoning_delta STREAM_REASONING A displayable reasoning delta.
stream_end STREAM_END The streaming request completed successfully.
stream_error STREAM_ERROR The streaming request failed before completion; the response is closed after this frame is sent.

Streaming response frame example:

event: stream_start
data: {"type":"STREAM_START","msgId":"...","correlationId":"req_001","action":"chat.completions","agentId":"agent_xxx","sessionId":"sess_001","data":{"requestId":"req_001","model":"<resolved-model>"}}
event: chunk
data: {"type":"STREAM_CHUNK","msgId":"...","correlationId":"req_001","action":"chat.completions","agentId":"agent_xxx","sessionId":"sess_001","data":{"content":"你好"}}
event: stream_end
data: {"type":"STREAM_END","msgId":"...","correlationId":"req_001","action":"chat.completions","agentId":"agent_xxx","sessionId":"sess_001","data":{"requestId":"req_001","content":"你好","finishReason":"stop","usage":{"totalTokens":20}}}

5.2 WebSocket

Streaming responses over WebSocket are not wrapped in SSE text format and do not include lines such as event or data. The server sends each streaming event back over the same WebSocket connection as a separate envelope message. The client uses the correlationId in the response to match the requestId provided in the request.

For WebSocket clients, STREAM_CHUNK and STREAM_REASONING are used only for real-time display. Near the end of the transfer, STREAM_END.data contains the complete response result. You must use the response result for business processing.

Request example:

{
 "type": "REQUEST",
 "requestId": "req_001",
 "action": "chat.completions",
 "agentId": "agent_xxx",
 "sessionId": "sess_001",
 "payload": {
 "message": "hello",
 "stream": true
 }
}

Streaming response frame example:

{"type":"STREAM_START","msgId":"...","correlationId":"req_001","action":"chat.completions","agentId":"agent_xxx","sessionId":"sess_001","data":{"requestId":"req_001","model":"<resolved-model>"}}
{"type":"STREAM_CHUNK","msgId":"...","correlationId":"req_001","action":"chat.completions","agentId":"agent_xxx","sessionId":"sess_001","data":{"content":"你好"}}
{"type":"STREAM_END","msgId":"...","correlationId":"req_001","action":"chat.completions","agentId":"agent_xxx","sessionId":"sess_001","data":{"requestId":"req_001","content":"你好","finishReason":"stop","usage":{"totalTokens":20}}}

5.3 Error Semantics

  • If HTTP SSE fails before it starts, the server returns a standard error response envelope with the corresponding HTTP status.
  • If HTTP SSE fails after it starts, the HTTP status has already been sent. The server returns event: stream_error, with the data field's type set to STREAM_ERROR, and then closes the response.
  • On WebSocket failure, the server returns an ERROR or STREAM_ERROR JSON frame; correlationId still corresponds to the requestId in the request frame.
  • After STREAM_END or STREAM_ERROR is received, the current streaming request is complete, and no further events will follow.

5.4 Client Handling Recommendations

  • The top-level headers in a streaming envelope have the same meaning as in a non-streaming envelope and are returned only when the server-side envelope headers are not empty.
  • SSE response bodies always use UTF-8 encoding. The client should read bytes, explicitly decode them as UTF-8, and only then perform event framing and JSON parsing.
  • The client should ignore unknown EVENT.action values to avoid compatibility issues when the server adds new process events.