Skip to main content
api.ApplicationRealtime(appID) opens a Server-Sent Events stream and returns a *rest.RealtimeStream. Iterate it with stream.Next() until io.EOF.
client := rest.NewClient(os.Getenv("SQUARECLOUD_API_KEY"))
defer client.Close()

api := rest.New(client)

Consuming the stream

stream, err := api.ApplicationRealtime("abc123def456abc123def456")
if err != nil {
	panic(err)
}
defer stream.Close()

for {
	event, err := stream.Next()
	if err == io.EOF {
		break // stream ended (e.g. 10-minute TTL reached)
	}
	if err != nil {
		panic(err)
	}

	fmt.Println(event.Name, string(event.Data))
}
Always defer stream.Close() — an unclosed stream keeps one of your account’s connection slots occupied.

Event shape

The stream emits two kinds of frames:
  • System events — connection lifecycle messages: REALTIME_CONNECTING, REALTIME_TIMEOUT, REALTIME_DISCONNECTED, REALTIME_RECONNECT and REALTIME_ERROR.
  • message events — the application payload. Data is opaque to the SDK, usually JSON — unmarshal it yourself:
if event.Name == "message" {
	var payload map[string]any
	if err := json.Unmarshal(event.Data, &payload); err == nil {
		fmt.Println(payload)
	}
}

Connection limits

A single account can keep at most 5 simultaneous connections open, and each connection lasts up to 10 minutes (its TTL). When the TTL is reached the stream ends with io.EOF — reconnect in a loop to stay subscribed.
for {
	stream, err := api.ApplicationRealtime("abc123def456abc123def456")
	if err != nil {
		panic(err)
	}

	for {
		event, err := stream.Next()
		if err != nil {
			break // io.EOF on TTL — reconnect
		}
		fmt.Println(event.Name, string(event.Data))
	}

	stream.Close()
}

Cancellation

Attach a context.Context with rest.WithContext to stop the stream from the outside:
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

stream, err := api.ApplicationRealtime("abc123def456abc123def456", rest.WithContext(ctx))
if err != nil {
	panic(err)
}
defer stream.Close()

// cancel() from another goroutine ends the stream