Stream Run
curl --request GET \
--url https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream \
--header 'Authorization: Bearer <token>' \
--header 'x-workspace-id: <x-workspace-id>'import requests
url = "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream"
headers = {
"x-workspace-id": "<x-workspace-id>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-workspace-id': '<x-workspace-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"x-workspace-id: <x-workspace-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-workspace-id", "<x-workspace-id>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream")
.header("x-workspace-id", "<x-workspace-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-workspace-id"] = '<x-workspace-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyDigital Employees
Stream Run
Opens a Server-Sent Events (SSE) stream to follow a run in real time.
GET
/
digital-employees
/
{employeeId}
/
runs
/
{runId}
/
stream
Stream Run
curl --request GET \
--url https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream \
--header 'Authorization: Bearer <token>' \
--header 'x-workspace-id: <x-workspace-id>'import requests
url = "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream"
headers = {
"x-workspace-id": "<x-workspace-id>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-workspace-id': '<x-workspace-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"x-workspace-id: <x-workspace-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-workspace-id", "<x-workspace-id>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream")
.header("x-workspace-id", "<x-workspace-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-workspace-id"] = '<x-workspace-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyThe stream endpoint uses Server-Sent Events (SSE) to deliver incremental run output. Connect to this endpoint while a run is
running to receive output as it is generated.
Code Examples
curl --request GET \
--url 'https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'x-workspace-id: YOUR_WORKSPACE_ID' \
--header 'Accept: text/event-stream' \
--no-buffer
const https = require('https');
const options = {
hostname: 'api.tess.im',
path: '/digital-employees/{employeeId}/runs/{runId}/stream',
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'x-workspace-id': 'YOUR_WORKSPACE_ID',
'Accept': 'text/event-stream'
}
};
const req = https.request(options, (res) => {
res.on('data', (chunk) => {
const lines = chunk.toString().split('\n');
lines.forEach((line) => {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
if (data.delta) process.stdout.write(data.delta);
if (data.status === 'completed') console.log('\nRun completed.');
}
});
});
});
req.on('error', console.error);
req.end();
import requests
import json
url = "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"x-workspace-id": "YOUR_WORKSPACE_ID",
"Accept": "text/event-stream"
}
with requests.get(url, headers=headers, stream=True) as response:
for line in response.iter_lines():
if line:
decoded = line.decode('utf-8')
if decoded.startswith('data: '):
data = json.loads(decoded[6:])
if 'delta' in data:
print(data['delta'], end='', flush=True)
if data.get('status') == 'completed':
print('\nRun completed.')
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream",
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"x-workspace-id: YOUR_WORKSPACE_ID",
"Accept: text/event-stream"
],
CURLOPT_WRITEFUNCTION => function($curl, $data) {
$lines = explode("\n", $data);
foreach ($lines as $line) {
if (str_starts_with($line, 'data: ')) {
$payload = json_decode(substr($line, 6), true);
if (isset($payload['delta'])) echo $payload['delta'];
if (($payload['status'] ?? '') === 'completed') echo "\nRun completed.";
}
}
return strlen($data);
}
]);
curl_exec($curl);
curl_close($curl);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream"))
.header("Authorization", "Bearer YOUR_API_KEY")
.header("x-workspace-id", "YOUR_WORKSPACE_ID")
.header("Accept", "text/event-stream")
.GET()
.build();
HttpResponse<java.io.InputStream> response = client.send(request,
HttpResponse.BodyHandlers.ofInputStream());
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body()))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("data: ")) {
System.out.println(line.substring(6));
}
}
}
package main
import (
"bufio"
"fmt"
"net/http"
"strings"
)
func main() {
client := &http.Client{}
req, _ := http.NewRequest("GET",
"https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream", nil)
req.Header.Add("Authorization", "Bearer YOUR_API_KEY")
req.Header.Add("x-workspace-id", "YOUR_WORKSPACE_ID")
req.Header.Add("Accept", "text/event-stream")
resp, _ := client.Do(req)
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "data: ") {
fmt.Println(line[6:])
}
}
}
using System.Net.Http;
using System.IO;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");
client.DefaultRequestHeaders.Add("x-workspace-id", "YOUR_WORKSPACE_ID");
client.DefaultRequestHeaders.Add("Accept", "text/event-stream");
using var response = await client.GetAsync(
"https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream",
HttpCompletionOption.ResponseHeadersRead);
using var stream = await response.Content.ReadAsStreamAsync();
using var reader = new StreamReader(stream);
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
if (line != null && line.StartsWith("data: "))
Console.WriteLine(line.Substring(6));
}
require 'uri'
require 'net/http'
uri = URI('https://api.tess.im/digital-employees/{employeeId}/runs/{runId}/stream')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer YOUR_API_KEY'
request['x-workspace-id'] = 'YOUR_WORKSPACE_ID'
request['Accept'] = 'text/event-stream'
http.request(request) do |response|
response.read_body do |chunk|
chunk.split("\n").each do |line|
if line.start_with?('data: ')
puts line[6..]
end
end
end
end
Headers
Authorization: Pass your API key as a Bearer token in the
Authorization header: Authorization: Bearer YOUR_API_KEY.integer
required
ID of the workspace. Required for all Digital Employees API requests.
Path Parameters
integer
required
The ID of the digital employee.
integer
required
The ID of the run to stream.
SSE Events
| Event | Description |
|---|---|
delta | Incremental output chunk. Contains partial text output as the run progresses. |
complete | Final snapshot with status, output, rendered_output, and run metadata. Signals the end of the stream. |
heartbeat | Keep-alive comment (: heartbeat) sent periodically to maintain the connection. |
delta Event Shape
data: {"delta": "The financial report..."}
complete Event Shape
data: {"status": "completed", "output": "The financial report for Q2 is complete.", "rendered_output": "...", "execution_id": 9001}
Connect to this endpoint only while the run status is
running. If the run has already finished, use Get Run Output instead.⌘I