Skip to main content
A public agent accepts sessions straight from the browser: the SDK calls the session endpoint with just an agent_id, no API key and no server of your own. The platform gates access with three controls: an agent-level public switch (off by default), a required origin allowlist, and rate limiting. Use this mode for demos, marketing pages, and support bubbles where standing up a backend isn’t worth it. For production apps with their own users, authenticated sessions are usually the better fit. See when to use session tokens instead.

Enable public access

1

Publish the agent

Public sessions always run the agent’s published configuration. An unpublished agent rejects session creation. See Versions & publishing.
2

Turn on the public switch

On the agent’s Deploy page in the console, turn on Public access. It is off by default. Until you enable it, sessions require authentication.
3

Add allowed origins

On the same page, list every web origin that may start sessions under Allowed origins (allowed_origins in the API). The allowlist is required: a request whose Origin doesn’t match any entry is rejected with 403.

Start a session from the browser

Pass agentId to the SDK and it creates the session directly with the Fish Audio API, then connects the audio.
The response is the same session token an authenticated request returns. The SDK consumes it internally. Everything else (events, methods, client tools) works exactly as in the Web SDK.

Origin matching

An entry matches only on exact scheme + host + port. The host is case-insensitive, and a trailing slash on an entry is tolerated.
localhost and 127.0.0.1 are different origins. If you develop against both, list both:

Rate limiting

Public session creation is rate limited on two dimensions at once: per client IP and per agent. Either limit being exceeded rejects the request. Sessions started on a public agent are billed to the workspace that owns the agent.
If legitimate traffic outgrows these limits, or you need per-user quotas, move to authenticated sessions: your backend becomes the gate, and the platform-side public limits no longer apply.

Treat public input as untrusted

On the public path, the entire session request originates in the visitor’s browser. The platform enforces its own guardrails (public sessions accept only the language and voice_id overrides, rejecting everything else with 400), but anything that passes through verbatim is attacker-controllable:
  • metadata is stored and returned exactly as sent, never interpreted by the platform. When you read it back in conversation history or webhooks, treat it as untrusted data, never as proof of who the visitor is.
  • dynamic_variables are chosen by the page that starts the session. Don’t inject anything through them that the visitor shouldn’t control. See Dynamic variables.
For trusted attribution (a verified end_user_id, server-set metadata), create sessions from your backend instead.

Errors

Public-mode failures surface as FishAgentError codes on AgentSession.start():

When to use session tokens instead

Public mode trades control for zero setup. Prefer the sessionToken flow (your backend calls the session endpoint with an API key and hands the token to the browser) when any of these apply:
  • The agent should stay private rather than callable by anyone who loads your page.
  • You need trusted attribution: an end_user_id and metadata set by your server, not the browser.
  • You want server-side control of overrides, dynamic_variables, or tool_events instead of accepting the browser’s values.
  • You already authenticate users and want your own quotas per account, not IP-based platform limits.
The SDK call changes by one field: pass { sessionToken } instead of { agentId }. See Authenticated sessions for the full flow.

Going further

Authenticated sessions

The session token flow in full: request fields, lifetime, errors.

Web SDK

Events, methods, and client tools, identical in both modes.

React SDK

Hooks and components for React apps.

Conversation history

Review what public visitors said to your agent.