WebSocket

Stream events over one connection.

Open one connection and send one event per text frame. Auth uses the same X-Api-Key header, so connect from your server.

GET wss://ingress.sarama.tech/c/{CLIENT_ID}/t/{THREAD_ID}/ws

Frame body is the same as the event format:

{ "source": "my-stream", "payload": { "any": "json" } }

Sarama replies on the same socket:

ReplyMeaning
{"accepted":"<uuid>"}Event queued.
{"error":"invalid_json", ...}Frame is not valid JSON.
{"error":"rate_limited"}Plan rate limit hit. Slow down.
{"error":"concurrency_limited"}Too many in flight.
{"error":"too_large"}Event over size limit.

Node with the ws package (bun add ws).

import WebSocket from "ws";

const ws = new WebSocket(
	`wss://ingress.sarama.tech/c/${CLIENT_ID}/t/${THREAD_ID}/ws`,
	{ headers: { "X-Api-Key": API_KEY } },
);

ws.on("open", () => {
	ws.send(
		JSON.stringify({
			source: "my-stream",
			payload: { action: "transfer" },
		}),
	);
});
ws.on("message", (msg) => console.log(msg.toString()));

When Sarama is busy it stops reading from the socket. Your writes block instead of dropping events.