# Realtime subscriptions

URL: https://docs.spacerun.co/docs/platform/guides/realtime

> Connect to Mercure, handle user events, renew credentials, and recover from unavailable realtime.

Use realtime to refresh the caller's UI after changes. Prerequisites: a signed-in user, a configured Mercure hub, and the `apiRequest` helper from [Quickstart](https://docs.spacerun.co/docs/platform/guides/quickstart).

## Connect to your topic

1. Call [getMyRealtimeAccess](https://docs.spacerun.co/docs/platform/reference/profile/getMyRealtimeAccess).
2. Use the returned hub URL, topic pattern and subscriber token; the hub token is separate from the Platform access token.
3. Register named event handlers and refresh the relevant API data when an event arrives.

```ts
const { url, topic, token } = await apiRequest("/v1/me/realtime");
const hub = new URL(url);
hub.searchParams.append("topic", topic);
hub.searchParams.set("authorization", token);
const events = new EventSource(hub);
const refresh = () => apiRequest("/v1/me").then(profile => console.log(profile));
events.addEventListener("profile.updated", refresh);
events.addEventListener("session.revoked", refresh);
events.addEventListener("session.active", event => {
  const data = JSON.parse((event as MessageEvent).data);
  console.log("Game active", data.sessionId);
});
events.addEventListener("session.ended", event => {
  const data = JSON.parse((event as MessageEvent).data);
  console.log("Game ended", data.sessionId, data.endReason);
});
```

The initial API response has the following shape; URLs and tokens below are placeholders:

```json
{"url":"https://realtime.example.com/.well-known/mercure","topic":"/users/3f6c2a1e-8b4d-4e7a-9c1f-2d5b6a7e8f90/*","token":"<SUBSCRIBER_JWT>"}
```

`profile.updated` carries changed field names. Game lifecycle events carry `sessionId` and nullable `endReason`. Revocation events concern login sessions or device authorizations, rather than the running game instance. Re-fetch authoritative data; an event is a notification, not a complete object snapshot.

## Expiry and recovery

The subscriber token expires after one hour. Before expiry, close the old EventSource, fetch fresh credentials and create a new connection. Refresh an expired Platform JWT through Supabase before requesting them. Clear renewal timers and call `events.close()` when the view unmounts.

A 503 `realtime_unavailable` means the hub is not configured. Continue with normal API reads and periodic refresh. EventSource reconnects after network interruptions, but an expired subscriber token needs replacement. Events are best effort: do not rely on receiving every event or treat them as a durable billing/session history. Reads after reconnect restore the current state.
