Protoface Session Tokens vs API Keys: Which Should Your Realtime Avatar App Use?

Protoface API keys vs session tokens for realtime avatar apps: secure backend auth, browser-safe ephemeral joins, and embed flow.
Introduction
When you add a realtime avatar to an app, you’re usually connecting three moving parts: a client that can receive media, a service that generates or streams the avatar video, and some authenticated control plane that creates sessions, applies instructions, and manages billing. The security question is simple on paper but easy to get wrong in practice: should the browser or frontend hold an API key, or should it receive a short-lived session token instead?
For a developer building a voice agent, support bot, or interactive web experience on Protoface, the answer depends on where the request originates and what it needs to do. By the end of this post, you should be able to choose the right credential type for each surface, understand the attack surface you’re creating, and avoid the common mistakes that leak long-lived secrets into places they don’t belong.
API keys: powerful, long-lived, and only for trusted backends
An API key is a bearer secret. Whoever has it can act as your application within the permissions attached to that key. In practice, that means it is appropriate for server-to-server calls, deployment pipelines, backend workers, and internal admin tools. It is not appropriate for JavaScript running in a browser, Electron renderer processes without hardening, mobile apps you do not fully control, or anything else you should assume will be inspected by a user.
With Protoface, API keys are used to authenticate calls to the REST API at api.protoface.com for creating and managing avatars and realtime sessions. That’s exactly where a long-lived secret belongs: on a trusted backend that can keep it out of the client, rotate it, and apply additional business logic before making an upstream call.
The important thing to notice is not the exact payload, which may vary by endpoint, but the trust boundary: the backend holds the secret, makes the request, and returns only the minimum data the client needs to continue. That pattern gives you control over rate limiting, audit logging, account mapping, and abuse prevention.
Session tokens: short-lived, scoped, and designed for the client
A session token is the opposite of an API key in operational terms. It should be narrowly scoped, short-lived, and safe to hand to an untrusted client because it can only do a small set of actions for a limited time. If an attacker steals it, the damage window should be small and the capabilities should be constrained.
For realtime avatar apps, this usually means the browser needs a way to join or continue a specific session, but not the ability to create arbitrary sessions, read all usage, or enumerate avatars. That’s especially true when the client is establishing a media connection, such as WebRTC, where the browser must hold ephemeral connection data but should not be able to mint those credentials itself.
Think of the distinction this way:
API key: “This backend is allowed to manage my Protoface account and sessions.”
Session token: “This specific client may join this specific realtime session for a short period.”
That split is what keeps a browser leak from turning into an account-wide compromise.
How realtime avatars usually flow
Realtime avatar systems are mostly a coordination problem. A voice agent receives audio, produces text or intermediate reasoning, and then streams synthesized speech and synchronized video to the client. Depending on your architecture, the avatar may be rendered in a browser, embedded in an iframe, or attached to a voice-agent runtime such as LiveKit. The credential model should follow the direction of trust.
A backend-controlled flow often looks like this:
Your server authenticates the user with your app’s own identity system.
Your server calls the Protoface REST API using an API key to create a session.
Your server receives a session identifier or token and returns only that client-safe credential to the browser.
The browser uses that token to connect to the realtime avatar session.
This is the same basic pattern used by most media and collaboration systems: secrets stay server-side, and the frontend gets ephemeral join credentials. The browser should never be able to create or modify resources beyond the narrow session it was explicitly invited into.
When an API key is the wrong tool
The most common mistake is putting a bearer key in frontend code because it is “just a demo.” Demos become production surprisingly fast. Once a key ships to the browser, you’ve lost control of who can copy it, how often it can be replayed, and whether it gets scraped by bots or extensions. Even if you rotate it later, the browser bundle, logs, and cache may keep the old value alive longer than you expect.
Use a simple test: if the credential would let an attacker do more than join the current session, it does not belong in the browser. That includes creating avatars, changing instructions, inspecting other users’ sessions, or pulling usage data.
There are also practical reasons to keep API keys out of the client:
They complicate key rotation because every deployed frontend becomes a secret distribution channel.
They make least-privilege harder, since browser code often needs only one narrow action.
They increase blast radius when a token is logged, copy-pasted, or exposed in source maps.
Designing a safe session-issuing backend
If your app needs to initiate a realtime avatar session from the browser, the backend should act as a broker. It receives the authenticated user request, decides whether that user is allowed to start or join the session, and then uses the API key to create the server-side resource. Only after that should it return a session token or other ephemeral join data to the frontend.
A minimal Python example looks like this:
In a real implementation, your backend would not just print the response. It would validate the caller, enforce business rules, and pass only the client-usable part of the response back to the browser. The exact fields in the response are documented in the docs; the architectural point is that the API key never leaves the trusted server.
How Protoface fits: REST API on the server, session token in the client
This is where the platform’s split surfaces matter. Use the REST API when you need to create avatars, manage sessions, and perform control-plane operations from your backend. Use a session token when the browser needs to join a specific realtime session and nothing more. That division aligns with the product’s intended surfaces and avoids exposing long-lived credentials in the frontend.
If you are using the Python SDK, the same rule applies: it belongs in trusted code, not in client-side JavaScript. A backend service can create the session and then hand the frontend only the ephemeral data required to attach the media connection.
For LiveKit-based voice agents, the integration story is similar. The agent runtime stays server-side, and the avatar plugin attaches the video face to that trusted process. If you’re using the LiveKit plugin, the examples in the relevant repository are a good reference for how the avatar surface is wired into a voice agent without pushing secrets into the browser; see the repo at github.com/protoface-ai/protoface-quickstart-openai-realtime for one of the realtime integration patterns.
One exception: customer-managed iframe embeds
There is one particularly clean way to avoid the whole question for website embeds: use an iframe flow that never exposes an API key in the browser at all. In that setup, the parent page can be locked down with an origin allowlist, while Protoface handles the interactive avatar session inside the embed. You can also constrain voice selection, custom instructions, and runtime limits such as per-IP and duration caps.
That is the right answer when you want a drop-in avatar on a website and you do not want to build or secure a backend just to broker session credentials. The operational advantage is simple: the frontend never gets a bearer key, so there is nothing for a malicious script on the page to exfiltrate.
Practical decision guide
If you’re still deciding, use this rule of thumb:
Backend only: API key.
Browser, iframe, or other untrusted client: session token or no credential at all if the embed is fully managed.
Realtime voice agent runtime: keep credentials in the trusted agent service, not in the end-user client.
For most production systems, the correct architecture is boring and asymmetric: a trusted backend holds the API key; the client receives a short-lived session token; and the media connection is established with the narrowest possible privilege. That pattern scales better, is easier to audit, and survives security review without a lot of hand-waving.
Conclusion
For a realtime avatar app, the difference between an API key and a session token is not just semantic. It is the boundary between account-wide authority and client-specific access. API keys are for trusted servers that create and manage resources. Session tokens are for browsers and other untrusted clients that only need to join a specific realtime session.
If you keep that line clean, you can build voice agents, conversational video experiences, and embedded avatars without leaking long-lived secrets into the frontend. If you want implementation details, endpoint shapes, or quickstarts for your stack, start with the docs and the relevant example repos, then wire your backend as the credential broker rather than letting the browser talk to the control plane directly.
