SSE Streaming Guide
Details of SSE streaming responses from AGENTIC STAR Chat API. This guide covers the connection lifecycle, response objects, agent-specific extension fields, and error handling.
How to read this guide
Agents on the Marketplace edition are built by the adopting company itself, using the AGENTIC STAR Platform SDK. An SSE response therefore has two parts: what the platform always does, and what appears only if the agent implements it. Understand this split before writing any branching logic.
What the platform always does
The following is identical no matter which agent you connect to.
- Connection and termination —
: connected/: heartbeat/data: [DONE], the role chunk withmessageInfo, and the response headers - The launch notice the platform sends when a conversation starts (one
delta.contentchunk) - Filling in Task field names and defaults, normalizing
files, stripping internal keys - Converting text to plain text when
outputFormatis not specified - Closing with
finishReason: "stop"— the SDK runner sends a terminal event for both success and failure - The
cancelled: truechunk once a cancellation is accepted
What appears only if the agent implements it
| Item | Condition for it to appear |
|---|---|
delta.tasks | The agent sends a tool event with metadata.actionType set. Without it, the event is not a Task and falls through to the body (delta.content) |
delta.interaction | The agent implements asking the user something |
choice.deliverables | The agent sends deliverable files |
The contents of delta.content | The final answer, intermediate progress, and reasoning all flow here, with nothing to tell them apart |
These may or may not arrive. Confirm what the agent you connect to actually sends before implementing client-side branching.
Overview
AGENTIC STAR Chat API delivers responses via SSE (Server-Sent Events) streaming. Each chunk is in OpenAI-compatible ChatCompletionChunk format and includes agent-specific extension fields (task information, interaction requests, etc.).
- Content-Type is
text/event-stream; charset=utf-8 - Each event is a JSON line prefixed with
data: - Stream end is signaled by
data: [DONE] - For long-running agent tasks, reconnection and cancellation endpoints are available
Connection Lifecycle
After a request to POST /v1/chat/completions, an SSE connection is established and events are delivered in the following order.
SSE Event Flow
: connected ← SSE connection established comment
data: {"createdAt":"...","model":"AGENTIC STAR","choices":[{"index":0,"delta":{"role":"assistant","messageInfo":{...}}}]}
↑ Role chunk (once)
data: {"createdAt":"...","model":"AGENTIC STAR","choices":[{"index":0,"delta":{"content":"sales"}}]}
data: {"createdAt":"...","model":"AGENTIC STAR","choices":[{"index":0,"delta":{"content":"data"}}]}
data: {"createdAt":"...","model":"AGENTIC STAR","choices":[{"index":0,"delta":{"content":"is..."}}]}
↑ Content chunks (multiple times)
data: {"createdAt":"...","model":"AGENTIC STAR","choices":[{"index":0,"delta":{"content":"...","tasks":[{"messageId":"...","conversationId":"...","actionType":"command_execution","title":"Command execution","status":"completed","timestamp":1773499412706}]}}]}
↑ Chunk containing task execution info (multiple times)
: heartbeat ← Connection keep-alive comment (approx. 15s interval, inserted only during idle periods)
data: {"createdAt":"...","model":"AGENTIC STAR","choices":[{"index":0,"delta":{"content":"..."},"finishReason":"stop"}]}
↑ Final chunk (with finishReason)
data: [DONE] ← Stream end signal
Detail of Each Phase
| Phase | Description |
|---|---|
: connected | SSE comment line. Indicates the connection has been established. |
| Role chunk | First data event. delta contains role: "assistant" and messageInfo (conversationId, messageId). |
| Content chunks | Diff of text content. delta.content contains appended text. The text format is controlled by the request outputFormat — plain text by default ("markdown" preserves Markdown). May also contain agent task execution info (delta.tasks). Delivered multiple times. |
: heartbeat | SSE comment line. Keeps the connection alive during long idle periods (to avoid proxy idle timeouts). Inserted at roughly 15-second intervals. Since it does not start with data:, typical clients ignore it automatically. |
| Final chunk | Chunk with finishReason set. May contain status (execution state) and deliverables (artifact files). |
data: [DONE] | Stream end signal. The SSE connection is closed after this. |
Unless the request specifies outputFormat: "markdown", delivered text is converted to plain text with Markdown notation removed. This applies to delta.content and to delta.interaction.content. Specify outputFormat: "markdown" to receive Markdown as written.
Response Headers
| Header | Description |
|---|---|
Content-Type | text/event-stream; charset=utf-8 |
X-Conversation-Id | Conversation ID. For new conversations, the server-generated ID is returned. |
X-Message-Id | Assistant response message ID. |
Response Objects
Each SSE data: line is composed of the following object hierarchy.
ChatCompletionChunk
└─ choices[]
└─ Choice
├─ delta … Delta object (diff data)
├─ finishReason … Completion reason
├─ status … Agent execution state
└─ deliverables … Artifact files
ChatCompletionChunk
The top-level object of each SSE event.
| Parameter | Type | Description |
|---|---|---|
createdAt | string | Chunk generation date/time (ISO 8601 format) |
model | string | Model name. "AGENTIC STAR" |
choices | array | Array of Choice objects (always 1 element) |
Choice
Each element of the choices array. AGENTIC STAR always contains only 1 element.
| Parameter | Type | Description |
|---|---|---|
index | number | Always 0 |
delta | object | Diff data (Delta object below) |
finishReason | string | null | "stop" (successful completion), "error" (error), or null (streaming) |
status | object | { processing: boolean, unfinished: boolean } — Agent execution state |
deliverables | array | Array of artifact files generated by the agent |
cancelled | boolean | Present as true only on the chunk that acknowledges a cancellation. The field is absent from ordinary chunks |
Delta
Diff data for each chunk. The fields included vary depending on the chunk type.
| Parameter | Type | Appearance | Description |
|---|---|---|---|
role | string | First only | Sent only in the first chunk. Fixed as "assistant". |
messageInfo | object | First only | { conversationId, messageId } — Message identification info |
content | string | Multiple times | Diff of text content |
tasks | array | Multiple times | Agent task execution info (array of Task objects) |
interaction | object | Conditional | User interaction request (option presentation, etc.) |
Agent Extension Fields
AGENTIC STAR adds agent-specific extension fields to the OpenAI-compatible format.
| Field | Level | Description |
|---|---|---|
delta.tasks | Delta | Agent task execution info |
delta.interaction | Delta | User interaction request |
choice.status | Choice | Agent execution state |
choice.deliverables | Choice | List of artifact files |
delta.tasks
Agent task execution info. Delivered as a delta.tasks array in SSE chunks when actions such as tool execution, file creation, or search occur. Sent each time a task status updates; the typical number of Tasks per chunk is 1. delta.tasks coexists with delta.content in the same chunk.
For details of the Task object, see Task Data Model.
An example of what is delivered. The actionType and metadata values vary with the implementation of the agent you connect to.
{
"createdAt": "2026-03-14T15:00:53.059Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"finishReason": null,
"delta": {
"content": "Running a command",
"tasks": [{
"messageId": "5b47837a-...",
"conversationId": "09071b95-...",
"callId": "call-1",
"actionType": "command_execution",
"title": "Command execution",
"description": "Running a command",
"status": "in_progress",
"metadata": { "call_id": "call-1", "command": "ls -la" },
"timestamp": 1773499412706,
"createdAt": "2026-03-14T14:43:32.708Z",
"updatedAt": "2026-03-14T14:43:32.708Z"
}]
},
"status": { "processing": true, "unfinished": true }
}]
}
delta.interaction
Sent when the agent asks the user for input while executing a task.
The SDK provides the means — EventType.USER_INTERACTION_REQUIRED and metadata.interaction_type — but when to ask, and whether to ask at all, is up to the agent implementation. An agent that implements no interaction never emits delta.interaction. Check whether the agent you connect to uses interactions before building for them.
On emitting this event the agent stops its execution loop and closes the turn. The client must therefore present the content to the user and send the answer in the next request to continue the conversation. Without that, a conversation with an interactive agent stops there.
| Parameter | Type | Required | Description |
|---|---|---|---|
interactionType | string | ✓ | "question" | "choice" | "confirmation" |
content | string | Body of the interaction message | |
options | string[] | Array of options. Present only for choice (at most 10 entries, 200 characters each). Do not hard-code the number of elements; present the array as given. |
| interactionType | Purpose | How the SDK emits it |
|---|---|---|
question | Ask for a free-form answer | USER_INTERACTION_REQUIRED + interaction_type: "question" |
choice | Present options and have the user pick one | USER_INTERACTION_REQUIRED + interaction_type: "choice" + options[] |
confirmation | Ask the user to approve or reject | USER_INTERACTION_REQUIRED + interaction_type: "confirmation" |
Send the answer as text in the next POST /v1/chat/completions with the same conversationId. There is no path for returning an answer inside the SSE stream. When options is present, present them as choices and send the user's selection back as text. question and confirmation carry no options, so build the answer from the text in content.
Example of question:
"interaction": {
"interactionType": "question",
"content": "What period should the output cover?"
}
Example of choice:
"interaction": {
"interactionType": "choice",
"content": "Which output format would you like?",
"options": ["PDF", "Excel", "Markdown"]
}
Example of confirmation:
"interaction": {
"interactionType": "confirmation",
"content": "May I delete this file?"
}
choice.status
A field included at the Choice level in the final chunk. Indicates the agent's execution state.
| Parameter | Type | Description |
|---|---|---|
processing | boolean | Whether the agent is continuing background processing. Typically transitions together with unfinished. If true, subsequent events can be received via reconnection. |
unfinished | boolean | Whether the task is incomplete. Typically transitions together with processing. Both false means normal completion; both true means processing is still ongoing. |
"status": { "processing": false, "unfinished": false }
choice.deliverables
A field included at the Choice level in the final chunk. List of artifact files generated by the agent.
| Parameter | Type | Description |
|---|---|---|
filename | string | File name |
filepath | string | File path (relative path for download) |
source | string | "agent" (agent-generated) or "user" (user-uploaded). |
isPrimary | boolean | Whether it is a primary artifact |
createdAt | string | Creation date/time (ISO 8601 format) |
mimeType | string? | MIME type (e.g., "application/pdf", "image/png", "text/markdown"). Omitted when it cannot be determined from filename |
size | number? | File size (bytes). Omitted when 0 or below |
"deliverables": [{
"filename": "report.pdf",
"filepath": "/files/output/report.pdf",
"source": "agent",
"isPrimary": true,
"createdAt": "2026-03-14T10:30:05.000Z",
"mimeType": "application/pdf",
"size": 4201846
}]
Task Data Model
The delta.tasks array contains Task objects that represent actions the agent has executed. Each Task consists of "fields common to all Tasks" and "a variable part whose structure is switched by actionType".
The SSE connection lifecycle, the ChatCompletionChunk / Choice / Delta structures, choice.status, choice.deliverables, and the Task field names and defaults listed under "Common fields" below are guaranteed by the platform.
The actionType values, the keys and structure of metadata, and the wording of title / description / content are decided by the agent that produces the response. The platform neither validates nor transforms them; it delivers them as sent.
Common fields
Fields that appear in every Task.
| Field | Type | Description |
|---|---|---|
messageId | string | ID of the message the task belongs to |
conversationId | string | ID of the conversation the task belongs to |
actionType | string | Discriminator that determines the variant structure (actionType details) |
status | string | Task state. One of in_progress / completed / failed / error / pending. When the agent omits it, the platform fills in a default (in_progress or pending), so it is never empty. Tool-specific detailed statuses are stored in metadata.status and are a separate value from this field |
callId | string | null | Carries a value only when the agent supplied metadata.call_id; otherwise null. Start and result Tasks are paired by the same value |
title | string | Short heading of the task type or target (for display) |
description | string | Progress message or supplementary explanation (for display) |
content | string | Task output body (for display, can be long) |
metadata | object | Structure varies by actionType (see actionType details) |
files | TaskFile[] | Related files (TaskFile structure — see below) |
timestamp | number | Task timestamp (Unix milliseconds) |
createdAt | string | Creation date/time (ISO 8601) |
updatedAt | string | Update date/time (ISO 8601) |
title / description / content are human-readable text fields. Do not use them as branching conditions in your program. For branching, use actionType / status / metadata.sub_event_type.
| Field | Typical use |
|---|---|
title | Short heading of the task type or target (e.g. a tool name or target name) |
description | Progress message or supplementary explanation |
content | Body of the tool output |
Future implementations may add new fields to actionType / metadata / common fields. Client implementations should safely ignore any fields not documented here.
TaskFile structure
Structure of each element in files: TaskFile[].
| Field | Type | Description |
|---|---|---|
filename | string | File name |
size | number | File size (bytes) |
filepath | string | Download URL or file path inside the working directory |
mimeType | string? | MIME type (e.g., "application/pdf", "image/png", "text/markdown"). Omitted when it cannot be determined from filename |
actionType and metadata
Agents on the Marketplace edition are built by the adopting company itself, using the AGENTIC STAR Platform SDK. This section assumes that. The contents of delta.tasks[] therefore vary with the agent you connect to. The platform guarantees the Task field names and their defaults, but it neither validates nor transforms the values — it delivers them exactly as the agent sent them.
| What is determined | Who determines it |
|---|---|
| Task field names (actionType / status / title / description / metadata / files / callId / timestamp) | Platform |
| Defaults when a field is omitted | Platform |
actionType values | Agent |
metadata keys and structure | Agent |
Wording of title / description / content | Agent |
Deliverables listed in files | Agent |
If actionType / title / description are omitted, an empty string is stored. status is never empty: when omitted, the platform fills in a default (in_progress or pending). timestamp is assigned by the platform. callId is taken from metadata.call_id, and is null when absent.
Values that appear in actionType
With the SDK, an agent can set metadata.actionType to one of these seven values.
| actionType | Purpose |
|---|---|
command_execution | Command execution |
code_execution | Code execution |
file_operation | File operation |
browser_action | Browser operation |
search_result | Search results |
image_search | Image preview |
markdown_display | Markdown rendering |
For how the agent sets them, see the Events / Streaming Guide.
actionType is optional in the SDK. However, the platform excludes a Task that carries no actionType from delta.tasks and delivers its body as delta.content instead. So if the agent does not set metadata.actionType, tool execution information never appears in delta.tasks at all.
In the SDK, the start and completion of a tool run are expressed as EventType.TOOL_START / TOOL_RESULT. Both carry one of the seven actionType values above, so pair them using callId (metadata.call_id): two Tasks sharing the same value describe one tool run.
What arrives as body text
All of the following events arrive as delta.content. Nothing distinguishes one kind from another.
| SDK event | The agent's intent |
|---|---|
`PROGRESS_MESSAGE` | Loading indicator while working |
`THOUGHT_MESSAGE` | The agent's reasoning |
`PHASE_START` / `PROGRESS_UPDATE` | Phase start and progress updates |
`COMPLETION_SUCCESS` | The final answer |
The final answer, intermediate progress, and reasoning all flow into delta.content, and there is no way for a client to separate them. To isolate the final answer, wait for the chunk that carries finishReason: "stop".
Completion and errors
The SDK sends COMPLETION_SUCCESS as the terminal event for both success and failure (COMPLETION_FAILURE does not close the turn). The stream therefore always closes with finishReason: "stop". An error raised inside the agent does not produce finishReason: "error"; it arrives as delta.content describing the error.
The finishReason: "error" case and the SSE error chunks described under Error Handling below occur only when the platform itself fails.
How the response reaches you
A Marketplace agent posts its execution results to the platform webhook (to the URL in the WEBHOOK_URL environment variable, HMAC-signed). That webhook payload is the source of the SSE response described in this document, and the SDK (run_marketplace_agent / create_marketplace_handler) is what builds it.
| What the SDK sends | Where it appears in the external API |
|---|---|
chunk_type: "task_created" | One element of delta.tasks[] |
chunk_type: "content" | delta.content; with interaction_type, also delta.interaction |
deliverable_files | choice.deliverables |
The first chunk comes from the platform
When a conversation starts, the platform delivers one delta.content chunk announcing that the agent has been launched, before the agent itself returns anything. The wording is fixed per request language — in English, "Agent (name) is now executing your task."
This chunk does not become a Task. Because it carries no actionType, it is not included in delta.tasks; it arrives only as delta.content. Note that it is not text produced by the agent.
Fields the platform strips
Of the values sent by the agent, the following are removed before reaching the external API.
| Target | Reason |
|---|---|
Every key starting with _ (both at the Task level and inside metadata) | Internal use |
user / taskId | Internal pipeline use |
Each element of files is normalized to filename / size / filepath / mimeType (see TaskFile structure).
Guidance for client implementations
- Branch on
actionTypeonly after confirming the values the target agent actually sends. The seven values above are what can be set; which ones appear is up to the agent. - Make unknown
actionTypevalues and unknownmetadatakeys safe to ignore. Agent updates can introduce new ones. - If you only need to display progress,
title/description/contentplusstatusare enough. These four carry the same meaning across any agent. - Do not branch program logic on
title/description/content— they are human-readable text.
Reconnection
Reconnect to the SSE stream of an in-progress conversation. Used to recover from network disconnection.
GET /v1/chat/completions/{conversationId}
Usage Example
# Reconnect to an in-progress conversation
curl -N https://api.fd.agenticstar.tm.softbank.jp/api/v1/chat/completions/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $TOKEN"
Reconnection is only possible for in-progress conversations. For completed conversations, 404 Not Found is returned. Results of completed conversations can be retrieved via the resource API (GET /v1/conversations/{conversationId}/messages).
Cancellation
Cancel an in-progress conversation and interrupt agent execution.
POST /v1/chat/completions/{conversationId}/cancel
Usage Example
curl -X POST https://api.fd.agenticstar.tm.softbank.jp/api/v1/chat/completions/550e8400-e29b-41d4-a716-446655440000/cancel \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
Response
{
"conversationId": "550e8400-e29b-41d4-a716-446655440000",
"cancelled": true
}
What the stream receives
Once a cancellation is accepted, a connected SSE stream receives one chunk like the following, followed by data: [DONE].
{
"createdAt": "2026-03-14T10:30:07.000Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": { "content": "Cancelled" },
"finishReason": "stop",
"cancelled": true
}]
}
delta.content is the fixed string "Cancelled". finishReason is "stop", not "error", so use choice.cancelled to tell a cancellation apart from a normal completion.
Error Handling
Errors are returned in 2 formats depending on when they occur.
Errors Before Stream Start (HTTP Errors)
Errors that occur before the SSE connection is established. Returned as JSON in a normal HTTP response.
| Status | Description |
|---|---|
400 | Invalid request parameters (model, messages, stream, etc.) |
401 | Authentication token is invalid or not specified |
409 | The specified conversation is currently being processed |
HTTP 400 error response:
{
"error": {
"type": "invalid_request_error",
"message": "Parameter 'model' is required",
"code": "missing_parameter",
"param": "model",
"suggested_action": "Please provide the required parameter"
}
}
Errors During Streaming (SSE Error Chunk)
Errors that occur in the backend during SSE streaming. Delivered as a ChatCompletionChunk with finishReason set to "error".
data: {
"createdAt": "2026-03-14T10:30:00.000Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": { "content": "An error occurred..." },
"finishReason": "error"
}]
}
data: [DONE]
Recovery Strategy
| Error Type | Recommended Action |
|---|---|
| HTTP error (400/401) | Check request parameters or authentication info and resend |
| HTTP 409 Conflict | Wait for conversation processing to complete or cancel and resend |
| SSE error chunk | Resume conversation with a new message or start a separate conversation |
| Connection loss | Attempt reconnection via GET /v1/chat/completions/{conversationId} |
Complete Response Example
A typical sequence: role chunk, the platform launch notice, tasks, then the final chunk.
// 1. Role chunk (once, first)
data: {
"createdAt": "2026-03-14T10:30:00.000Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": {
"role": "assistant",
"messageInfo": {
"conversationId": "550e8400-e29b-41d4-a716-446655440000",
"messageId": "660f9511-f3ac-52e5-b827-557766551111"
}
}
}]
}
// 2. Launch notice sent by the platform (not agent output)
data: {
"createdAt": "2026-03-14T10:30:00.120Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": { "content": "Agent Sales Analyst is now executing your task." }
}]
}
// 3. Tool run starts (paired with its completion by callId)
data: {
"createdAt": "2026-03-14T10:30:01.500Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": {
"content": "Running a command",
"tasks": [{
"messageId": "660f9511-f3ac-52e5-b827-557766551111",
"conversationId": "550e8400-e29b-41d4-a716-446655440000",
"callId": "call-1",
"actionType": "command_execution",
"status": "in_progress",
"title": "Command execution",
"description": "Running a command",
"metadata": { "call_id": "call-1", "command": "python3 analyze.py" },
"timestamp": 1710410001500,
"createdAt": "2026-03-14T10:30:01.500Z",
"updatedAt": "2026-03-14T10:30:01.500Z"
}]
},
"status": { "processing": true, "unfinished": true }
}]
}
// 4. Tool run completes (same callId as 3)
data: {
"createdAt": "2026-03-14T10:30:04.200Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": {
"content": "The command finished",
"tasks": [{
"messageId": "660f9511-f3ac-52e5-b827-557766551111",
"conversationId": "550e8400-e29b-41d4-a716-446655440000",
"callId": "call-1",
"actionType": "command_execution",
"status": "completed",
"title": "Command execution",
"description": "The command finished",
"metadata": { "call_id": "call-1", "command": "python3 analyze.py", "output": "rows=1204" },
"timestamp": 1710410004200,
"createdAt": "2026-03-14T10:30:04.200Z",
"updatedAt": "2026-03-14T10:30:04.200Z"
}]
},
"status": { "processing": true, "unfinished": true }
}]
}
// 5. Final chunk (with status and deliverables)
data: {
"createdAt": "2026-03-14T10:30:05.456Z",
"model": "AGENTIC STAR",
"choices": [{
"index": 0,
"delta": { "content": "Here are the analysis results." },
"finishReason": "stop",
"status": { "processing": false, "unfinished": false },
"deliverables": [{
"filename": "report.pdf",
"filepath": "/files/output/report.pdf",
"source": "agent",
"isPrimary": true,
"createdAt": "2026-03-14T10:30:05.000Z",
"mimeType": "application/pdf",
"size": 4201846
}]
}]
}
// 6. End of stream
data: [DONE]