GET /api/events/stream
curl --request GET \
--url https://sluice.sh/api/api/events/streamimport requests
url = "https://sluice.sh/api/api/events/stream"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://sluice.sh/api/api/events/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://sluice.sh/api/api/events/stream",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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://sluice.sh/api/api/events/stream"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://sluice.sh/api/api/events/stream")
.asString();require 'uri'
require 'net/http'
url = URI("https://sluice.sh/api/api/events/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyReal-time & Health
GET /api/events/stream
Server-Sent Events stream for real-time job, worker, and queue updates.
GET
/
api
/
events
/
stream
GET /api/events/stream
curl --request GET \
--url https://sluice.sh/api/api/events/streamimport requests
url = "https://sluice.sh/api/api/events/stream"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://sluice.sh/api/api/events/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://sluice.sh/api/api/events/stream",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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://sluice.sh/api/api/events/stream"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://sluice.sh/api/api/events/stream")
.asString();require 'uri'
require 'net/http'
url = URI("https://sluice.sh/api/api/events/stream")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyOpens a persistent SSE connection that streams real-time updates for a specific connection. The dashboard uses this endpoint to provide live updates without polling.
Authentication
Session cookie (dashboard).The SSE endpoint authenticates via session cookies only — it cannot be consumed by external scripts or tools that don’t share the browser session. API key authentication for all endpoints, including SSE, is planned for V1.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
connectionId | string | Yes | UUID of the connection to stream events for. |
types | string | No | Comma-separated event types to filter (e.g., job,worker,queue). If omitted, all event types are streamed. |
Event format
Events follow the SSE specification:event: job:state_change
data: {"id":"a1b2c3d4...","name":"app.tasks.send_email","state":"completed","previousState":"active","timestamp":"2026-02-27T10:30:00.000Z"}
event: worker:heartbeat
data: {"id":"d4e5f6a7...","hostname":"celery@worker-1","state":"online","activeJobs":3}
event: queue:snapshot
data: {"name":"default","depth":42,"consumers":4}
event: heartbeat
data: {"timestamp":"2026-02-27T10:30:15.000Z"}
Event types
| Event | Description |
|---|---|
job:state_change | A job’s state changed (new job, started, completed, failed, etc.). |
worker:heartbeat | A worker sent a heartbeat with its current status. |
worker:state_change | A worker came online or went offline. |
queue:snapshot | Updated queue depth and consumer count. |
heartbeat | Keep-alive event sent every 15 seconds. |
Connection handling
- The SSE connection stays open indefinitely until the client disconnects.
- A
heartbeatevent is sent every 15 seconds to keep the connection alive through proxies and load balancers. - If the connection drops, reconnect with the same URL. The browser’s
EventSourceAPI handles reconnection automatically.
Example (JavaScript)
const eventSource = new EventSource(
"/api/events/stream?connectionId=550e8400-e29b-41d4-a716-446655440000"
);
eventSource.addEventListener("job:state_change", (event) => {
const job = JSON.parse(event.data);
console.log(`Job ${job.name} → ${job.state}`);
});
eventSource.addEventListener("worker:heartbeat", (event) => {
const worker = JSON.parse(event.data);
console.log(`Worker ${worker.hostname}: ${worker.activeJobs} active jobs`);
});
eventSource.onerror = () => {
console.log("SSE connection lost, reconnecting...");
};