> ## Documentation Index
> Fetch the complete documentation index at: https://hanabiaiinc-fish-772-enterprise-versions.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Your Agent

> Choose where users meet your agent and who may start sessions — widget, SDKs, or phone; public or authenticated

Your agent is one artifact with many front doors. Deploying it is two independent decisions:

1. **Where users meet your agent** — a prebuilt widget, your own UI built on the SDKs, a phone number, or a custom client.
2. **Who may start sessions** — anyone visiting your pages, or only clients your backend has vouched for.

Every surface runs the same agent with the same published configuration, and the browser surfaces work with either access mode.

<Note>
  Publishing gates every channel: sessions always run the agent's **published**
  configuration, and creating a session against an agent that has never been
  published fails. [Publish](/agents/deploy/versions-publishing) before wiring
  up any channel.
</Note>

## Where users meet your agent

In increasing order of integration effort:

<CardGroup cols={2}>
  <Card title="Widget" icon="puzzle-piece" href="/agents/deploy/widget">
    Drop a prebuilt call widget into your site — two lines of HTML, zero build
    step.
  </Card>

  <Card title="Your own UI" icon="js" href="/agents/deploy/web-sdk">
    Build a custom experience with the [Web SDK](/agents/deploy/web-sdk) or
    [React SDK](/agents/deploy/react-sdk) — events, transcripts, audio controls.
  </Card>

  <Card title="Phone" icon="phone" href="/agents/telephony/phone-numbers">
    Bind a number and callers dial straight in — no client code at all.
  </Card>

  <Card title="Custom client" icon="network-wired" href="/agents/deploy/protocol">
    On a stack the SDKs don't cover, implement the [wire
    protocol](/agents/deploy/protocol) directly.
  </Card>
</CardGroup>

## Who may start sessions

The widget and the SDKs each work with **either** access mode — pick per agent. Phone numbers skip this decision entirely: inbound calls connect through [telephony](/agents/telephony/inbound-calls), not a browser session.

<CardGroup cols={2}>
  <Card title="Public agents" icon="globe" href="/agents/deploy/public-agents">
    The client connects with just an `agentId` — no backend, gated by an origin
    allowlist and rate limits.
  </Card>

  <Card title="Authenticated sessions" icon="server" href="/agents/deploy/authenticated-sessions">
    Your backend creates a short-lived session token with your API key — trusted
    attribution and full control.
  </Card>
</CardGroup>

|                           | Public agent ID                                                             | Session token                         |
| ------------------------- | --------------------------------------------------------------------------- | ------------------------------------- |
| Credential in browser     | None                                                                        | Short-lived session token             |
| Requires                  | Agent set to public + allowed origins                                       | Your own backend endpoint             |
| Session parameters set by | The SDK (`overrides`, `dynamicVariables`, `language`, `toolEvents` options) | Your backend, in the creation request |
| Best for                  | Demos, marketing pages, low-friction embeds                                 | Production apps with signed-in users  |

## Still deciding?

| You are building                                   | Start with                                                                                                                       |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| A call button on an existing site, no build step   | [Widget](/agents/deploy/widget) with [public access](/agents/deploy/public-agents)                                               |
| A demo or marketing page without a backend         | [Web SDK](/agents/deploy/web-sdk) on a [public agent](/agents/deploy/public-agents)                                              |
| Voice calls inside a web app with signed-in users  | [Web SDK](/agents/deploy/web-sdk) with [authenticated sessions](/agents/deploy/authenticated-sessions)                           |
| A React or Next.js frontend                        | [React SDK](/agents/deploy/react-sdk)                                                                                            |
| A phone line callers dial in to                    | [Phone numbers](/agents/telephony/phone-numbers) and [transfers](/agents/telephony/transfers)                                    |
| Server-side session creation and history retrieval | [Authenticated sessions](/agents/deploy/authenticated-sessions) and [conversation history](/agents/monitor/conversation-history) |
| A client on a stack the SDKs don't cover           | [Wire protocol](/agents/deploy/protocol)                                                                                         |

## How a browser session starts

For private agents, your backend creates the session — your API key never ships to the browser. The browser SDK takes the resulting session token and handles audio and transport from there.

```bash Your backend theme={null}
curl --request POST https://api.fish.audio/v1/agent/sessions \
  --header "Authorization: Bearer $FISH_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{ "agent_id": "YOUR_AGENT_ID" }'
# → 201 session token — return it to your frontend as-is
```

```javascript Your frontend theme={null}
import { AgentSession } from "@fishaudio/agent-client";

// sessionToken = the create-session response, passed through unchanged
const session = await AgentSession.start({ sessionToken });
```

<Tip>
  Agents marked [public](/agents/deploy/public-agents) skip the backend step
  entirely — the SDK connects with just an `agentId`, gated by an origin
  allowlist and rate limits.
</Tip>

For phone calls there is no client integration: assign a number, and inbound calls connect directly to your agent — which can [transfer callers](/agents/telephony/transfers) to another number mid-call. See [Phone numbers](/agents/telephony/phone-numbers).

## Going further

<CardGroup cols={2}>
  <Card title="Versions & publishing" icon="rocket" href="/agents/deploy/versions-publishing">
    The publish step every channel depends on.
  </Card>

  <Card title="Authenticated sessions" icon="server" href="/agents/deploy/authenticated-sessions">
    The full session-creation reference — request fields, token lifetime,
    errors.
  </Card>

  <Card title="Conversation history" icon="clock-rotate-left" href="/agents/monitor/conversation-history">
    List sessions and read full transcripts over REST.
  </Card>

  <Card title="Wire protocol" icon="code" href="/agents/deploy/protocol">
    The wire-level session contract, for building your own client.
  </Card>
</CardGroup>
