A run executes an assistant on a thread. The assistant processes all thread messages and appends its response as a new message.
Prerequisites
Before you begin:
An API key configured as an environment variable
An existing assistant
An existing thread with at least one message
How runs work
queued --> in_progress --> completed
\-> requires_action --> (submit tool outputs) --> queued ...
\-> failed
\-> cancelled
\-> expired
\-> incompletequeued: The run is queued for processing.
in_progress: The assistant is processing the thread messages.
requires_action: The assistant invoked a function tool and is waiting for the tool output. Submit the output through the Submit tool outputs endpoint to resume the run.
completed: The run finished successfully. Retrieve the assistant's response from the thread messages.
failed: The run encountered an error. Check
last_errorfor details.cancelled: The run was cancelled.
expired: The run timed out before completing.
incomplete: The run ended without fully completing.
cancelling: A cancellation is in progress.
No dedicated cancel endpoint exists. Implement cancellation logic in your application if needed.
API operations
Operation | Method | Endpoint |
POST |
| |
GET |
| |
GET |
| |
POST |
| |
POST |
| |
SDK only | N/A |
Base URL: https://dashscope-intl.aliyuncs.com/api/v1
Create a run
POST /api/v1/threads/{thread_id}/runs
Starts an assistant on a thread. Supports streaming and non-streaming responses.
Request parameters
Parameter | Type | Required | Description |
thread_id | string | Yes | The thread ID (URL path parameter). |
assistant_id | string | Yes | The assistant to run. |
model | string | No | Overrides the model defined in the assistant. Example: |
instructions | string | No | Overrides the instructions defined in the assistant. |
tools | array | No | Overrides the tool list defined in the assistant. See Tool authentication for plug-in auth details. |
metadata | object | No | Key-value pairs to attach to the run. |
stream | boolean | No | Set to |
temperature | float | No | Controls randomness (higher = more diverse output). |
top_p | float | No | Probability threshold for nucleus sampling. |
top_k | integer | No | Size of the candidate token set during sampling. |
truncation_strategy | object | No | Message truncation strategy (only |
workspace | string | No | The workspace ID (required for sub-workspace API keys only). |
Tool authentication
For plug-in authentication, include the auth field:
{
"type": "plugin_type",
"auth": {
"type": "user_http",
"user_token": "<your-bearer-token>"
}
}The bearer token is added to plug-in request headers.
Sample request
cURL (non-streaming)
curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-d '{
"assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
"metadata": {}
}'cURL (streaming)
curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-d '{
"assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
"metadata": {},
"stream": true
}'Python (streaming)
import dashscope
import os
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
stream_iterator = dashscope.Runs.create(
'<your-thread-id>',
api_key=os.getenv("DASHSCOPE_API_KEY"),
assistant_id='<your-assistant-id>',
stream=True
)
for event, msg in stream_iterator:
print(event)
print(msg)Java (streaming)
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.runs.AssistantStreamMessage;
import com.alibaba.dashscope.threads.runs.RunParam;
import com.alibaba.dashscope.threads.runs.Runs;
import io.reactivex.Flowable;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void main(String[] args) throws ApiException, NoApiKeyException,
InputRequiredException, InvalidateParameter, InterruptedException {
Runs runs = new Runs();
RunParam runParam = RunParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.assistantId("<your-assistant-id>")
.stream(true)
.build();
Flowable<AssistantStreamMessage> run = runs.createStream("<your-thread-id>", runParam);
}
}Non-streaming response
Returns a run object.
{
"id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
"object": "thread.run",
"created_at": 1711517598169,
"thread_id": "thread_cc2a3e9d-436b-482b-91c5-377e0f376506",
"assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
"status": "in_progress",
"model": "qwen-max",
"instructions": "You are an intelligent assistant. You can call different tools based on user needs to provide answers. Use tools as appropriate.",
"tools": [
{"type": "search"},
{"type": "text_to_image"}
],
"metadata": {},
"request_id": "225292ff-9843-95d4-8591-b1377c33e2be"
}Streaming response
Returns a stream of SSE events. Each event has an event field and a data field (JSON object).
Streaming event types
Event | Description |
| A new thread was created (when run creates one). |
| The run was created. |
| The run entered the queue. |
| The run started processing. |
| A new run step was created. |
| A run step started processing. |
| Incremental update to a run step (e.g., tool call arguments). |
| A run step completed. |
| A new message was created. |
| Message generation started. |
| Incremental content added to the message. |
| Message generation completed. |
| The run completed (includes token usage in |
| The stream ended. Data value: |
Example SSE stream (abbreviated)
event:thread.run.created
data:{"id":"run_04fba6a3-...","object":"thread.run","status":"queued",...}
event:thread.run.in_progress
data:{"id":"run_04fba6a3-...","object":"thread.run","status":"in_progress",...}
event:thread.message.delta
data:{"id":"message_f4f68f6b-...","object":"thread.message.delta","delta":{"content":[{"type":"text","text":{"value":"999 multiplied"}}]}}
event:thread.message.completed
data:{"id":"message_f4f68f6b-...","object":"thread.message","content":[{"type":"text","text":{"value":"999 multiplied by 998 equals 997002."}}],...}
event:thread.run.completed
data:{"id":"run_04fba6a3-...","status":"completed","usage":{"input_tokens":419,"output_tokens":16,"total_tokens":435},...}
event:done
data:[DONE]SDK response parameters
SDK-specific fields (beyond standard run object):
Parameter | Type | Description |
status_code | integer | HTTP status code. |
code | string | Error code if the request failed. Python SDK only. |
message | string | Error details if the request failed. Python SDK only. |
List runs
GET /api/v1/threads/{thread_id}/runs
Returns a list of runs for a thread.
Request parameters
Parameter | Type | Required | Description |
thread_id | string | Yes | The thread ID (URL path parameter). |
limit | integer | No | Maximum number of runs to return. Default: |
order | string | No | Sort order by creation time. |
Sample request
cURL
curl 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs?limit=20&order=asc' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY"Python
import dashscope
from dashscope import Runs
import os
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
runs = Runs.list(
'<your-thread-id>',
api_key=os.getenv("DASHSCOPE_API_KEY"),
limit=1,
order='desc'
)Java
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ListResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void main(String[] args) throws ApiException, NoApiKeyException,
InputRequiredException, InvalidateParameter, InterruptedException {
Runs runs = new Runs();
GeneralListParam listRuns = GeneralListParam.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.build();
ListResult<Run> run = runs.list("<your-thread-id>", listRuns);
}
}Response
{
"object": "list",
"data": [
{
"id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
"object": "thread.run",
"created_at": 1711517598169,
"thread_id": "thread_cc2a3e9d-436b-482b-91c5-377e0f376506",
"assistant_id": "asst_46e95014-ccac-435d-b884-c97ac44a94d9",
"status": "completed",
"model": "qwen-max",
"tools": [
{"type": "search"},
{"type": "text_to_image"}
],
"metadata": {},
"usage": {
"prompt_tokens": 66,
"completion_tokens": 9,
"total_tokens": 75
}
}
],
"first_id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
"last_id": "run_3de634fa-75d4-4370-adcf-92ba2a60c396",
"has_more": false,
"request_id": "ff3d2aea-555c-9825-80ca-24029a636641"
}Response parameters
Parameter | Type | Description |
data | array | A list of run objects. |
first_id | string | The ID of the first run in the results. |
last_id | string | The ID of the last run in the results. |
has_more | boolean | Whether more runs are available beyond this page. |
Retrieve a run
GET /api/v1/threads/{thread_id}/runs/{run_id}
Returns a single run by ID.
Request parameters
Parameter | Type | Required | Description |
thread_id | string | Yes | The thread ID (URL path parameter). |
run_id | string | Yes | The run ID (URL path parameter). |
Sample request
cURL
curl 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs/run_3de634fa-75d4-4370-adcf-92ba2a60c396' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY"Python
import dashscope
from dashscope import Runs
import os
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
run = Runs.retrieve(
'<your-run-id>',
api_key=os.getenv("DASHSCOPE_API_KEY"),
thread_id='<your-thread-id>'
)Java
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void main(String[] args) throws ApiException, NoApiKeyException,
InputRequiredException, InvalidateParameter, InterruptedException {
Runs runs = new Runs();
String apiKey = System.getenv("DASHSCOPE_API_KEY");
Run run = runs.retrieve("<your-thread-id>", "<your-run-id>", apiKey);
}
}Response
Returns the run object that matches the specified ID.
Modify a run
POST /api/v1/threads/{thread_id}/runs/{run_id}
Updates run metadata.
Request parameters
Parameter | Type | Required | Description |
thread_id | string | Yes | The thread ID (URL path parameter). |
run_id | string | Yes | The run ID (URL path parameter). |
metadata | object | No | Key-value pairs to update. |
Sample request
cURL
curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_cc2a3e9d-436b-482b-91c5-377e0f376506/runs/run_3de634fa-75d4-4370-adcf-92ba2a60c396' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-d '{
"metadata": {
"user": "abc123"
}
}'Python
import dashscope
from dashscope import Runs
import os
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
run = Runs.update(
'<your-run-id>',
api_key=os.getenv("DASHSCOPE_API_KEY"),
thread_id='<your-thread-id>',
metadata={'newkey': 'newvalue'}
)Java
import java.util.HashMap;
import java.util.Map;
import com.alibaba.dashscope.common.UpdateMetadataParam;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void main(String[] args) throws ApiException, NoApiKeyException,
InputRequiredException, InvalidateParameter, InterruptedException {
Runs runs = new Runs();
Map<String, String> metadata = new HashMap<>();
metadata.put("key", "value");
UpdateMetadataParam updateParam = UpdateMetadataParam.builder()
.metadata(metadata)
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.build();
Run run = runs.update("<your-thread-id>", "<your-run-id>", updateParam);
}
}Response
Returns the updated run object.
Submit tool outputs and continue a run
POST /api/v1/threads/{thread_id}/runs/{run_id}/submit_tool_outputs
When status is requires_action and required_action.type is submit_tool_outputs, submit tool execution results to resume the run.
Submit all pending tool call outputs in one request. Partial submissions are not supported.
How tool output submission works
Create a run. The assistant processes the thread and decides whether to call a tool.
If a function tool is called, status changes to
requires_action.Read
required_action.submit_tool_outputs.tool_callsto get the function name, arguments, and tool call ID.Execute the function in your application and collect the result.
Submit the tool output through this endpoint.
The run resumes processing and eventually reaches a terminal state (
completed,failed, orexpired).
Request parameters
Parameter | Type | Required | Description |
thread_id | string | Yes | The thread ID (URL path parameter). |
run_id | string | Yes | The run ID. Must have status |
tool_outputs | array | Yes | Tool call results to return to the assistant. |
tool_outputs[].tool_call_id | string | No | The tool call ID from the |
tool_outputs[].output | string | Yes | The result from the tool execution. |
stream | boolean | No | Set to |
Sample request
cURL (non-streaming)
curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_9157dfad-71fd-4add-b7a9-1afa452d2d67/runs/run_99935dbd-e731-4bad-b450-60d9d6bf9a44/submit_tool_outputs' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-d '{
"tool_outputs": [
{
"tool_call_id": "",
"output": "rain"
}
]
}'cURL (streaming)
curl -X POST 'https://dashscope-intl.aliyuncs.com/api/v1/threads/thread_9157dfad-71fd-4add-b7a9-1afa452d2d67/runs/run_99935dbd-e731-4bad-b450-60d9d6bf9a44/submit_tool_outputs' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-d '{
"tool_outputs": [
{
"tool_call_id": "",
"output": "rain"
}
],
"stream": true
}'End-to-end example: function calling with tool output
Complete workflow: create an assistant with a custom function, run it, handle requires_action, submit tool outputs, and retrieve the response.
Python
import json
import sys
from http import HTTPStatus
import dashscope
from dashscope import Assistants, Messages, Runs, Steps, Threads
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def create_assistant():
# Create an assistant with a custom "big_add" function tool
assistant = Assistants.create(
model='qwen-max',
name='smart helper',
description='A tool helper.',
instructions='You are a helpful assistant. When asked a question, use tools wherever possible.',
tools=[{
'type': 'tools',
'tools': {
'name': 'big_add',
'description': 'Add to number',
'parameters': {
'type': 'object',
'properties': {
'left': {
'type': 'integer',
'description': 'The left operator'
},
'right': {
'type': 'integer',
'description': 'The right operator.'
}
},
'required': ['left', 'right']
}
}
}],
)
return assistant
def verify_status_code(res):
if res.status_code != HTTPStatus.OK:
sys.exit(res.status_code)
if __name__ == '__main__':
# Step 1: Create the assistant
assistant = create_assistant()
verify_status_code(assistant)
# Step 2: Create a thread
thread = Threads.create()
verify_status_code(thread)
# Step 3: Add a message to the thread
message = Messages.create(thread.id, content='bigAdd 87787 to 788988737.')
verify_status_code(message)
# Step 4: Create a run
message_run = Runs.create(thread.id, assistant_id=assistant.id)
verify_status_code(message_run)
# Step 5: Wait for the run to reach a terminal state
run_status = Runs.wait(message_run.id, thread_id=thread.id)
# Step 6: If the run requires tool output, submit it
if run_status.required_action:
tool_outputs = [{
'tool_call_id':
run_status.required_action.submit_tool_outputs.tool_calls[0].id,
'output':
'789076524'
}]
run = Runs.submit_tool_outputs(
message_run.id,
thread_id=thread.id,
tool_outputs=tool_outputs
)
verify_status_code(run)
# Step 7: Wait for the run to complete after submitting tool output
run_status = Runs.wait(message_run.id, thread_id=thread.id)
verify_status_code(run_status)
# Step 8: Retrieve the thread messages
msgs = Messages.list(thread.id)
print(json.dumps(msgs, default=lambda o: o.__dict__, sort_keys=True, indent=4))Java
import com.alibaba.dashscope.assistants.Assistant;
import com.alibaba.dashscope.assistants.AssistantParam;
import com.alibaba.dashscope.tools.ToolFunction;
import com.alibaba.dashscope.assistants.Assistants;
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ListResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.AssistantThread;
import com.alibaba.dashscope.threads.ThreadParam;
import com.alibaba.dashscope.threads.Threads;
import com.alibaba.dashscope.threads.messages.Messages;
import com.alibaba.dashscope.threads.messages.TextMessageParam;
import com.alibaba.dashscope.threads.messages.ThreadMessage;
import com.alibaba.dashscope.threads.runs.RequiredAction;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.RunParam;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.threads.runs.SubmitToolOutputsParam;
import com.alibaba.dashscope.threads.runs.ToolOutput;
import com.alibaba.dashscope.tools.FunctionDefinition;
import com.alibaba.dashscope.tools.ToolCallBase;
import com.alibaba.dashscope.utils.JsonUtils;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.victools.jsonschema.generator.Option;
import com.github.victools.jsonschema.generator.OptionPreset;
import com.github.victools.jsonschema.generator.SchemaGenerator;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfig;
import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
import com.github.victools.jsonschema.generator.SchemaVersion;
import com.alibaba.dashscope.tools.ToolCallFunction;
import com.alibaba.dashscope.utils.Constants;
public class AssistantFunctionCall {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
// Custom function tool: adds two numbers
public class AddFunctionTool {
private int left;
private int right;
public AddFunctionTool(int left, int right) {
this.left = left;
this.right = right;
}
public int call() {
return left + right;
}
}
static ToolFunction buildFunction() {
SchemaGeneratorConfigBuilder configBuilder =
new SchemaGeneratorConfigBuilder(
SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON);
SchemaGeneratorConfig config = configBuilder
.with(Option.EXTRA_OPEN_API_FORMAT_VALUES)
.without(Option.FLATTENED_ENUMS_FROM_TOSTRING)
.build();
SchemaGenerator generator = new SchemaGenerator(config);
ObjectNode jsonSchema = generator.generateSchema(AddFunctionTool.class);
FunctionDefinition fd = FunctionDefinition.builder()
.name("add")
.description("add two numbers")
.parameters(JsonUtils.parseString(jsonSchema.toString()).getAsJsonObject())
.build();
return ToolFunction.builder().function(fd).build();
}
// Step 1: Create an assistant with a custom function tool
static public Assistant createAssistant() throws ApiException, NoApiKeyException {
AssistantParam assistantParam = AssistantParam.builder()
.model("qwen-max")
.description("a helper assistant")
.name("system")
.instructions("You are a helpful assistant. When asked a question, use tools wherever possible.")
.tool(buildFunction())
.build();
Assistants assistants = new Assistants();
return assistants.create(assistantParam);
}
static public void run(String assistantId) throws ApiException, NoApiKeyException,
InvalidateParameter, InputRequiredException, InterruptedException {
// Step 2: Create a thread
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
// Step 3: Add a message and create a run
Messages messages = new Messages();
TextMessageParam textMessageParam = TextMessageParam.builder()
.role("user")
.content("Add 87787 to 788988737.")
.build();
ThreadMessage threadMessage = messages.create(assistantThread.getId(), textMessageParam);
Runs runs = new Runs();
RunParam runParam = RunParam.builder().assistantId(assistantId).build();
Run run = runs.create(assistantThread.getId(), runParam);
// Step 4: Poll until the run reaches a terminal state
while (true) {
if (run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION) ||
run.getStatus().equals(Run.Status.EXPIRED)) {
break;
} else {
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
// Step 5: Handle requires_action by submitting tool output
if (run.getStatus().equals(Run.Status.REQUIRES_ACTION)) {
RequiredAction requiredAction = run.getRequiredAction();
if (requiredAction.getType().equals("submit_tool_outputs")) {
ToolCallBase toolCall = requiredAction.getSubmitToolOutputs()
.getToolCalls().get(0);
if (toolCall.getType().equals("function")) {
String functionName = ((ToolCallFunction) toolCall).getFunction().getName();
String functionId = ((ToolCallFunction) toolCall).getId();
String functionArgument = ((ToolCallFunction) toolCall)
.getFunction().getArguments();
if (functionName.equals("add")) {
AddFunctionTool addFunction =
JsonUtils.fromJson(functionArgument, AddFunctionTool.class);
int sum = addFunction.call();
SubmitToolOutputsParam submitToolOutputsParam =
SubmitToolOutputsParam.builder()
.toolOutput(ToolOutput.builder()
.toolCallId(functionId)
.content(String.valueOf(sum))
.build())
.build();
run = runs.submitToolOutputs(
assistantThread.getId(), run.getId(), submitToolOutputsParam);
}
}
}
}
// Step 6: Poll again until the run completes
while (true) {
if (run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION) ||
run.getStatus().equals(Run.Status.EXPIRED)) {
break;
} else {
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
// Step 7: Retrieve the final messages
GeneralListParam listParam = GeneralListParam.builder().limit(100L).build();
ListResult<ThreadMessage> threadMessages =
messages.list(assistantThread.getId(), listParam);
for (ThreadMessage msg : threadMessages.getData()) {
System.out.println(msg);
}
}
public static void main(String[] args) throws ApiException, NoApiKeyException,
InputRequiredException, InvalidateParameter, InterruptedException {
Assistant assistant = createAssistant();
run(assistant.getId());
}
}Response
Returns the updated run object. When the run resumes, its status changes from requires_action to queued.
Wait for a run to complete
SDK only. Blocks until run reaches terminal state: cancelled, failed, completed, expired, or requires_action.
Sample code
Python
import dashscope
from dashscope import Runs
import os
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
run = Runs.wait(
'<your-run-id>',
api_key=os.getenv("DASHSCOPE_API_KEY"),
thread_id='<your-thread-id>'
)Java
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.utils.Constants;
public class AssistantFunctionCall {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void main(String[] args) throws ApiException, NoApiKeyException,
InputRequiredException, InvalidateParameter, InterruptedException {
Runs runs = new Runs();
String apiKey = System.getenv("DASHSCOPE_API_KEY");
Run run = runs.retrieve("<your-thread-id>", "<your-run-id>", apiKey);
// Poll until the run reaches a terminal state
while (true) {
if (run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION) ||
run.getStatus().equals(Run.Status.EXPIRED)) {
break;
} else {
Thread.sleep(1000);
}
run = runs.retrieve("<your-thread-id>", run.getId());
}
}
}Request parameters
Parameter | Type | Required | Description |
run_id | string | Yes | The run ID. |
thread_id | string | Yes | The thread ID. |
workspace | string | No | The workspace ID. Required only when the API key belongs to a sub-workspace. |
api_key | string | No | The API key. Defaults to the |
Response
Returns the run object in its terminal state.
Run object
Represents a run.
Example
{
"assistant_id": "asst_xxxx",
"cancelled_at": null,
"completed_at": null,
"created_at": 1735026246751,
"expires_at": null,
"failed_at": null,
"file_ids": [],
"id": "run_xxxx",
"instructions": "you are a helpful assistant",
"last_error": null,
"max_tokens": null,
"metadata": {},
"model": "qwen-plus",
"object": "thread.run",
"request_id": "req_xxxx",
"required_action": null,
"started_at": null,
"status": "in_progress",
"temperature": null,
"thread_id": "thread_xxxx",
"tool_choice": "auto",
"tools": [],
"top_k": null,
"top_p": null,
"truncation_strategy": null,
"usage": null
}Attributes
Attribute | Type | Description |
id | string | Unique identifier (format: |
object | string | Object type (always |
assistant_id | string | The assistant associated with this run. |
thread_id | string | The thread this run belongs to. |
status | string | Current status: |
model | string | The model used for this run. |
instructions | string | The instructions the assistant followed during this run. |
tools | array | The tools available to the assistant during this run. |
metadata | map | Up to 16 key-value pairs (keys: max 64 chars, values: max 512 chars). |
required_action | object | Action needed to proceed (e.g., submit tool outputs). |
last_error | object | Last error during run ( |
usage | object | Token usage ( |
created_at | integer | Unix timestamp (ms) when created. |
started_at | integer | Unix timestamp (ms) when started processing. |
completed_at | integer | Unix timestamp (ms) when completed. |
cancelled_at | integer | Unix timestamp (ms) when cancelled. |
failed_at | integer | Unix timestamp (ms) when failed. |
expired_at | integer | Unix timestamp (ms) when expired. |
FAQ
Q: How do I cancel a run that is in progress?
No dedicated cancel endpoint. Implement cancellation in your application.
Error codes
For failed API calls, see Error messages.