curl --request GET \
--url https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream \
--header 'Authorization: Bearer <token>'import requests
url = "https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/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://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/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>"
],
]);
$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://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream"
req, _ := http.NewRequest("GET", url, nil)
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://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body<string>{
"error": "Error message"
}{
"error": "Error message"
}{
"error": "Error message"
}{
"error": "Error message"
}Stream process logs in real time
Streams the stdout and stderr output of a process in real time: the output so far, then live output as the process writes it. Closes when the process exits or the client disconnects.
By default, output is plain text with stdout: or stderr: prefixes at the start of each source stream’s lines. Partial lines (e.g. prompts) are sent without waiting for a newline; their continuations have no new prefix. The other stream is not held back while a line is incomplete, and chronological order across stdout and stderr is not guaranteed.
This format does not provide unambiguous framing: output from the other stream, or a [keepalive] marker sent every 30 seconds, can appear inside an unfinished line. A later continuation can therefore lack a prefix identifying its source. Do not rely on this text stream to reconstruct stdout and stderr separately; request NDJSON for source-preserving streaming, or use GET /process//logs for separate output snapshots.
With Accept: application/x-ndjson, each line is a JSON object with type (stdout, stderr, keepalive, restart, truncated, or error) and optional data. Output records retain source identity and original bytes, including partial lines and newlines, for both retained history and live output. For encoding: "base64", decode data before concatenating bytes per source; this occurs for binary data or a UTF-8 character split across chunks. Chunk boundaries are arbitrary and ordering is collection order, not a strict chronology across streams.
keepalive has no output data. A quiet active stream sends an initial keepalive after attachment so clients can receive the response before sending stdin; subsequent keepalives are sent every 30 seconds. restart carries a supervisor restart notice, not process output. truncated reports a retention or slow-reader gap and must not be appended to stdout/stderr. error reports a streaming failure. The connection ends after the final process exit, including automatic restarts; there is no result record. Older processes without structured history return HTTP 409 for NDJSON; their text stream remains available.
curl --request GET \
--url https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream \
--header 'Authorization: Bearer <token>'import requests
url = "https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/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://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/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>"
],
]);
$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://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream"
req, _ := http.NewRequest("GET", url, nil)
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://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sbx-{sandbox_id}-{workspace_id}.{region}.bl.run/process/{identifier}/logs/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body<string>{
"error": "Error message"
}{
"error": "Error message"
}{
"error": "Error message"
}{
"error": "Error message"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Explicit application/x-ndjson opts into structured records; absent or wildcard Accept retains text/plain. Supported explicit media types honor q weights, preferring NDJSON on a tie.
Path Parameters
Process identifier (PID or name)
Response
Process output as prefixed text or NDJSON records
The response is of type string.
Was this page helpful?