Skip to content

Async operations

Some operations on Stream's API take longer than a single HTTP response can wait for. Hard-deleting channels, deleting users in bulk, exporting users or calls, and similar batch jobs return a task_id immediately and run in the background. To get the result, poll the task status endpoint.

Task statuses

A task moves through the following statuses:

  • pending: the task is queued and not running yet
  • running: the task is running and not completed yet
  • completed: the task finished successfully
  • failed: the task failed during its execution

The task status response carries the current status, a result payload whose shape depends on the task, and an error with failure details when the task failed.

Waiting on a task

The unified SDKs ship a helper that polls for you and surfaces the outcome as either a typed result (when the task completes) or a typed exception (when it fails or the wait elapses).

from getstream.exceptions import StreamTaskException, StreamTransportException

response = client.delete_channels(cids=["messaging:c1", "messaging:c2"], hard_delete=True)
task_id = response.task_id

try:
    result = client.wait_for_task(task_id)
    print("task completed:", result)
except StreamTaskException as e:
    print(f"task {e.task_id} failed: {e.description}")
except StreamTransportException as e:
    if e.error_type == "timeout":
        # wait elapsed; task may still be running on the server
        ...

The task and transport exceptions are part of the SDK exception hierarchy documented in Error handling.

Behavior

Task outcome Helper's reaction
status: "completed" Returns the task result payload.
status: "failed" Raises the SDK's task exception with task_id, error_type, description, stack_trace, version.
Deadline exceeded Raises the SDK's transport exception with error_type = "timeout". The task may still be running on the server.
Note:

Java exposes the server-side stack trace via getStackTraceText(), not getStackTrace(). The latter is reserved for the JVM's own Throwable.getStackTrace() (StackTraceElement[]).

Defaults

Parameter Default
Poll interval 1 second
Wait timeout 60 seconds

Override either knob if your task is expected to run longer, or if you want a tighter loop.

client.wait_for_task(task_id, poll_interval=5.0, timeout=600.0)

The async variant in your SDK (for example Python's AsyncStream.wait_for_task or .NET's WaitForTaskAsync) is non-blocking and accepts the same parameters.

Polling manually

If you need a custom polling loop (back-off, progress logging, external cancellation), call getTask yourself. The helper is a convenience over the same endpoint.

const response = await client.exportUsers({
  user_ids: ["<user id1>", "<user id2>"],
});

// poll this endpoint until the status is completed or failed
const taskResponse = await client.getTask({ id: response.task_id });

console.log(taskResponse.status === "completed");