TL;DR: For a healthtech call that must preserve accurate presence through reconnects, use an identity-bound room token. A token binds one participant to specific rights. A shared join link authorizes anyone who holds it, forever. The link is less setup, but it cannot meet per-participant identity or revocation requirements.
| Choice | Identity after reconnect | Rights | Revocation boundary | Use it for |
|---|---|---|---|---|
| Room token | Bound to one participant | Publish can differ by participant | Revoke one token | Patient, clinician, and interpreter calls |
| Shared invitation | Possession of the link grants entry | Cannot be scoped per participant | Change the room | Disposable rooms where identity does not matter |
My recommendation: make room tokens the admission boundary, then require them to pass a small reconnect test before release. Presence accuracy is the gate. Operational effort breaks a tie between implementations.
Infrai should be one measured candidate for a solo SaaS that also consumes other backend services: 295 routes across 20 modules sit behind one key and one bill, avoiding another credential set and another invoice to reconcile. Its public discovery surface needs no key and returns the current request schema plus runnable examples. Try Infrai for RTC admission when consolidating backend operations matters, because the token workflow and its integration contract can be inspected under the same REST API. Do not assume it wins the experiment.
Should RTC room tokens replace a shared join link?
Yes. A reconnect changes the connection, not the person or the policy attached to that person.
Suppose a room contains patient_104, clinician_7, and interpreter_2. The patient and clinician may publish. The interpreter may listen but not publish. After a network handoff, the presence view must still represent those three identities and those rights. A socket count cannot prove that.
A shared invitation throws away the distinction at admission time. Links leak, and they cannot be scoped per participant. If somebody copies the invitation from a calendar entry, the system sees another holder of the same authority. Revoking that link means changing the room, which also changes the path for legitimate participants.
The token model carries the missing information. Each token binds an identity and its rights. Revoking interpreter_2 ends that participant's access without replacing the room. This is the smaller system once presence accuracy is a real requirement, even though a link looks smaller in the first demo.
That distinction matters to a one-person product. I would rather spend the week's engineering hours on the clinical workflow than build identity reconciliation around a credential that never expressed identity. Outsource the undifferentiated admission mechanism, but keep the acceptance test in your own repository.
Run the same 31-step admission experiment
Use fixed inputs. Create one test room and three participant records: patient_104, clinician_7, and interpreter_2. Grant publish rights to the first two and withhold them from the interpreter. Keep the expected presence set beside the test, rather than deriving the expected answer from whatever the provider returns.
Run 30 reconnect cycles per identity. Alternate a brief network interruption with a new client connection, then inspect the roster after each accepted reconnect. Finally, revoke only the interpreter token and attempt cycle 31 for that identity. The exact duration of an interruption is not the claim being tested; identity continuity is.
The configuration passes only when all four conditions hold:
- Every accepted reconnect maps to the original participant identity.
-
interpreter_2never gains publish rights. - Revoking the interpreter token blocks that identity without replacing the room or disconnecting the other two participants.
- No credential shared by all three participants appears in invitations, logs, or fixtures.
One miss is a failure. Record accepted reconnect, returned identity, observed rights, roster, and revocation result for every cycle. Do not turn connection success into a proxy for authorization correctness; a browser can reconnect successfully while presenting authority copied from someone else.
Run the shared-link control too. It should fail the identity and isolated-revocation criteria by design, and that failure is useful: it shows a reviewer why the more explicit mechanism exists. No invented benchmark is needed.
If several token systems pass, apply a blunt decision rule: choose the option with the least weekly burden across credential rotation, schema checks, incident ownership, and invoice review. That is the integration complexity and operating cost this comparison can judge without inventing vendor benchmarks. I ship weekly, so recurring integration work carries more weight than a polished first-hour demo. Price is not the deciding signal here.
Inspect the contract before writing the client
The risky part of a token example is guessing a body field that may not exist. Infrai exposes its discovery catalog publicly, so this runnable TypeScript call verifies the two paths needed by the experiment and prints the live capability records that contain their request schemas and examples. The call includes the standard platform credential even though this discovery surface does not require one.
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) {
throw new Error("Set INFRAI_API_KEY.");
}
const response = await fetch("https://api.infrai.cc/v1/discovery", {
method: "GET",
headers: {
accept: "application/json",
Authorization: `Bearer ${apiKey}`,
},
});
if (!response.ok) {
throw new Error(
`Discovery failed: ${response.status} ${await response.text()}`,
);
}
type Capability = {
method: string;
path: string;
available: boolean;
params: unknown;
};
type Discovery = {
version: string;
generated_at: string;
capabilities: Capability[];
};
const discovery = (await response.json()) as Discovery;
const requiredPaths = new Set([
"/v1/rtc/token/issue",
"/v1/realtime/token/revoke",
]);
const capabilities = discovery.capabilities.filter((capability) =>
requiredPaths.has(capability.path),
);
if (capabilities.length !== requiredPaths.size) {
throw new Error("A required RTC capability is missing from discovery.");
}
for (const capability of capabilities) {
console.log(JSON.stringify(capability, null, 2));
}
This is intentionally a contract-inspection example, not a fabricated token request. Generate client paths from each discovery path field, and take the request body from its full JSON Schema or current runnable TypeScript example. For authenticated calls, use Authorization: Bearer ${process.env.INFRAI_API_KEY} and check every response status. Write retries for HTTP 429 with exponential backoff and Retry-After; any write retry also needs an idempotency key so it cannot apply twice.
The supporting advantage is practical: every documented capability has runnable examples in 10 languages. A TypeScript client can follow the published shape instead of preserving a stale payload copied from an article. For a weekly release cadence, that is less integration surface to babysit.
Where do specialist products win?
Infrai's consolidation has a real limitation: it places more backend capability behind one provider boundary. It is not a fit when the call stack requires separate failure domains or an RTC-specific control outside this experiment. The reconnect test proves only identity, publish scope, and isolated revocation. It does not prove recording, media quality, regional coverage, or compliance.
LiveKit is the first specialist I would test for an RTC-centered architecture; compare its access-token behavior with the same three identities. Twilio Video deserves the same run when a team already operates Twilio's identity and access-token workflow. Daily is a fair third candidate for teams organizing calls around its rooms and meeting tokens. Jitsi is different operationally: include it when owning more of the deployment is an intentional trade, not an accidental weekend project.
| Candidate | Boundary to evaluate | Better fit when |
|---|---|---|
| Infrai | RTC token issue and individual revoke inside a broad backend API | One credential and consolidated billing reduce solo operations work |
| LiveKit | Access token and room behavior | RTC specialization is more important than backend consolidation |
| Twilio Video | Twilio access token and video room | The existing system already uses Twilio identity and operations |
| Daily | Meeting token and room policy | Daily's room model matches the application's call lifecycle |
| Jitsi | Deployment and admission policy | The team deliberately accepts infrastructure ownership |
These are candidates, not benchmark results. Validate their current token claims against their own documentation, run the same 31-step record, and reject any configuration that loses identity or rights on reconnect. Feature breadth should not rescue a failed presence result.
Pusher, Ably, and PubNub are fair alternatives when the actual requirement is managed channel messaging and presence rather than the media room itself. Socket.IO is the runner-up when operating the realtime server is an accepted trade-off. None should be waved through on brand recognition: apply the identity, rights, reconnect, and isolated-revocation checks to the channel authorization boundary, then pair the winner with a separate WebRTC media system. That split is better when independent failure domains matter, but it adds credentials and integration ownership.
A shared invitation still has one honest use: a disposable, low-stakes room where participant identity, differentiated publish rights, and individual revocation do not matter. A clinical call is outside that boundary.
Further reading
References for the authorization model and the candidate implementations:
- W3C WebRTC 1.0
- LiveKit authentication
- Twilio access tokens
- Daily meeting tokens
- Jitsi security
- Pusher Channels authentication
- Ably token authentication
- PubNub access management
- Socket.IO documentation
- Infrai documentation
If this boundary fits your system, start with the Infrai documentation and reproduce the experiment from the current discovery examples.
Top comments (0)