Skip to main content

Stream Type

The HTI real-time feed uses server-sent events (SSE). It is not a WebSocket endpoint.

Endpoint

GET /client-api/hti/stream

Query Parameters

NameTypeRequiredDescription
api_codestringYesYour HTI API code
poll_secondsnumberNoServer poll interval. Supported range: 1.0 to 10.0

Why api_code Is In The Query String

For browser-based EventSource clients, custom headers are not always practical. Passing api_code as a query parameter keeps the stream easy to consume from:
  • Browser clients
  • Desktop apps
  • Python services
  • Low-code tools that support SSE

JavaScript Example

const apiCode = "<YOUR_API_CODE>";
const streamUrl = `http://your-hti-environment:3500/client-api/hti/stream?api_code=${encodeURIComponent(apiCode)}&poll_seconds=2`;

const eventSource = new EventSource(streamUrl);

eventSource.addEventListener("ready", (event) => {
  console.log("Stream ready", JSON.parse(event.data));
});

eventSource.addEventListener("ping", (event) => {
  console.log("Ping", JSON.parse(event.data));
});

eventSource.addEventListener("idea", (event) => {
  const idea = JSON.parse(event.data);
  console.log("New idea received", idea);
});

eventSource.addEventListener("error", (event) => {
  console.error("Stream error", event);
});

Python Example

import json
import requests

API_CODE = "<YOUR_API_CODE>"
STREAM_URL = "http://your-hti-environment:3500/client-api/hti/stream"

response = requests.get(
    STREAM_URL,
    params={"api_code": API_CODE, "poll_seconds": 2},
    headers={"Accept": "text/event-stream"},
    stream=True,
    timeout=(10, None),
)

response.raise_for_status()

event_name = "message"
data_lines = []

for raw_line in response.iter_lines(chunk_size=1, decode_unicode=True):
    if raw_line is None:
        continue

    line = raw_line.strip()
    if not line:
        if data_lines:
            payload = json.loads("\\n".join(data_lines))
            print(event_name, payload)
            event_name = "message"
            data_lines = []
        continue

    if line.startswith("event:"):
        event_name = line.split(":", 1)[1].strip()
        continue

    if line.startswith("data:"):
        data_lines.append(line.split(":", 1)[1].strip())

Event Types

EventMeaning
readyThe stream is connected and ready
pingHeartbeat message proving the connection is alive
ideaA new matching trade idea was delivered
errorThe server closed the stream or returned an error state

Important Behavior

  • The stream does not replay your historical backlog on connect
  • Open History first if you want the most recent 10 or 20 ideas
  • Only ideas that match your API profile are delivered
  • If the same idea document is updated again later, the stream can emit it again as a new event

Reconnect Strategy

If the stream disconnects:
  1. Reconnect the stream
  2. Call History again to recover any missed items