Sandbox · developer access

Get a token. Open a socket. Ship.

Sandbox tokens are free and rate-limited to a representative slice of the fabric. Same schema, same routing, same reconnect contract as production.

01 — Endpoint

One URL. Persistent. Resilient.

WebSocket Secure. Reconnect on close. Frame router separates control messages from flow records.

Endpoint
wss://sdaot.globalthreatintel.com/ws/aot/
Auth
Authorization: Bearer <SANDBOX_TOKEN>
Heartbeat check
every 2,000 ms
Reconnect
5,000 ms after unexpected close
Frame router
type · action · default flow record
Uniqueness
record_unique_id
02 — Reference clients

Pick a runtime. The contract is identical.

Three clients. Same router. Copy and ship.

typescript · firehose client
wss://
import WebSocket from "ws";

let lastHeartbeat = Date.now();

function connect() {
  const ws = new WebSocket("wss://sdaot.globalthreatintel.com/ws/aot/", {
    headers: { Authorization: `Bearer ${process.env.SIGNAL_FABRIC_TOKEN}` },
  });

  ws.on("open",   () => console.log("[fabric] connected"));
  ws.on("close",  () => setTimeout(connect, 5000));
  ws.on("error",  (e) => console.error("[fabric]", e.message));

  ws.on("message", (raw) => {
    lastHeartbeat = Date.now();
    const f = JSON.parse(raw.toString());
    route(f);
  });
}

setInterval(() => {
  if (Date.now() - lastHeartbeat > 10000) console.warn("[fabric] stale");
}, 2000);

connect();
03 — Frame router

Control plane first. Flow records by default.

Inbound frames are distinguished by type and action.

01
frame.type === "performanceMetrics"
fabric throughput · eventsPerMs, avgEventLoopMs
02
frame.action === "threatStream" && frame.type === "detection"
threat detection · detection{} + summary{}
03
frame.action === "allowlist.result"
outbound allowlist ack · status, type, value, risk_id
04
default
full Hadron flow record (see schema)

Need fields you don't see?

The contract is versioned. Field additions land additively. Tell us what your app needs to render and we'll wire it into the next core.