Skip to main content
CapOut supports two realtime transports:
  • WebSocket for long-lived interactive clients that may want to change subscriptions after connecting
  • SSE for simpler browser-friendly one-way event delivery
Both transports start with POST /ws/token.

1. Mint a realtime token

curl https://api.capout.ai/ws/token \
  -X POST \
  -H "capout-api-key: $CAPOUT_API_KEY"
Example response:
{
  "token": "rt_123",
  "organization_id": "org_123",
  "expires_at": "2026-04-14T14:45:00Z",
  "ws_url": "/ws/status",
  "sse_url": "/sse/status"
}
If the response contains relative paths, resolve them against https://api.capout.ai or wss://api.capout.ai.

WebSocket example

const tokenResponse = await fetch("https://api.capout.ai/ws/token", {
  method: "POST",
  headers: {
    "capout-api-key": process.env.CAPOUT_API_KEY
  }
}).then((res) => res.json());

const wsUrl = new URL(tokenResponse.ws_url, "wss://api.capout.ai");
wsUrl.searchParams.set("token", tokenResponse.token);
wsUrl.searchParams.append("document_id", "doc_123");

const socket = new WebSocket(wsUrl);

socket.addEventListener("open", () => {
  socket.send(JSON.stringify({
    action: "subscribe",
    document_ids: ["doc_123"]
  }));
});

socket.addEventListener("message", (event) => {
  console.log(JSON.parse(event.data));
});

SSE example

const tokenResponse = await fetch("https://api.capout.ai/ws/token", {
  method: "POST",
  headers: {
    "capout-api-key": process.env.CAPOUT_API_KEY
  }
}).then((res) => res.json());

const streamUrl = new URL(tokenResponse.sse_url, "https://api.capout.ai");
streamUrl.searchParams.set("token", tokenResponse.token);
streamUrl.searchParams.set("recent", "10");

const source = new EventSource(streamUrl);

source.onmessage = (event) => {
  console.log(JSON.parse(event.data));
};

Scoping subscriptions

You can scope the initial stream in two ways:
  • Repeat document_id to follow specific documents
  • Send recent=10 to follow the latest organization-owned documents

Reconnect behavior

Handle disconnects with token expiry in mind:
  1. Detect closure or error.
  2. Mint a fresh realtime token.
  3. Re-open the connection with the same document scope.