RAKLEdocs
API Reference

Streaming

Stream live job progress and the final result over Server-Sent Events.

View as Markdown

GET /v1/jobs/{id}/stream

Opens a text/event-stream SSE connection for one job. The stream replays prior events, then tails live until terminal (completed or failed), then closes.

curl -N https://api.orakle.xyz/v1/jobs/<job_id>/stream \
  -H "X-Orakle-API-Key: $ORAKLE_API_KEY"

-N disables curl buffering. Unknown or unowned jobs return 404 job_not_found.

Wire format

Standard SSE frames: event:, id: (monotonic integer), data: JSON, blank line.

event: stage
id: 3
data: {"event_type":"stage","job_id":"b7c1...","stage":"planning","message":"Planning strategy...","timestamp":"2026-05-15T12:00:03Z"}

See Events for every event type and payload.

Replay with Last-Event-Id

Send Last-Event-Id with the last id you processed. The server replays only higher sequences then continues live — so a dropped connection resumes without gaps or duplicates.

curl -N https://api.orakle.xyz/v1/jobs/<job_id>/stream \
  -H "X-Orakle-API-Key: $ORAKLE_API_KEY" \
  -H "Last-Event-Id: 3"

Keepalive

When idle, the server emits SSE comments to hold the connection open. Skip lines starting with :.

: keepalive

Consuming in Node

const res = await fetch(
  `https://api.orakle.xyz/v1/jobs/${jobId}/stream`,
  { headers: { "X-Orakle-API-Key": process.env.ORAKLE_API_KEY! } },
);

const reader = res.body!.getReader();
const decoder = new TextDecoder();
let buf = "";

for (;;) {
  const { value, done } = await reader.read();
  if (done) break;
  buf += decoder.decode(value, { stream: true });

  let i: number;
  while ((i = buf.indexOf("\n\n")) !== -1) {
    const frame = buf.slice(0, i);
    buf = buf.slice(i + 2);
    if (frame.startsWith(":")) continue; // keepalive

    const lines = frame.split("\n");
    const event = lines.find((l) => l.startsWith("event: "))?.slice(7);
    const data = lines.find((l) => l.startsWith("data: "))?.slice(6);
    if (data) handle(event, JSON.parse(data));
  }
}

Prefer the SDK

The SDKs handle streaming, reconnection, and Last-Event-Id replay, resolving a single typed result. Hand-roll SSE only for raw progress events or non-JS/Python clients.