# Web embed

URL: https://docs.bithuman.ai/platforms/web

> Put a live, talking avatar on any web page with one iframe.

One URL in an `<iframe>`: no npm package, no install and no secret in the browser.

## Before you start

The embed URL is `https://www.bithuman.ai/embed/<CODE>`, and the avatar listens and answers. By default it renders in the bitHuman cloud and streams to the page; with `render=local` it renders in the visitor's tab with WebGPU.

- A current browser. For lip-sync rendered in the tab, a usable GPU ([render in the tab](https://docs.bithuman.ai/platforms/web/webgpu)).
- An [agent code](https://docs.bithuman.ai/models/how-it-works#key-terms): `A23WJF0199` (the `wise-pup` sample avatar) or your own ([create your own avatar](https://docs.bithuman.ai/build/create-avatar)).
- For a private agent, an [embed token](https://docs.bithuman.ai/api/embedding) minted by your server.

## Authenticate

A public agent needs no credential. For a private agent, your server mints an [embed token](https://docs.bithuman.ai/api/embedding) with your API secret and passes it to the page. Sessions on your own agent bill your account per second, voice and AI included ([pricing](https://docs.bithuman.ai/pricing)).

## Run your first avatar

```html
<!doctype html>
<html>
  <body style="margin:0">
    <iframe src="https://www.bithuman.ai/embed/A23WJF0199"
            allow="microphone *" style="width:100%;height:100vh;border:0"></iframe>
  </body>
</html>
```

Expected: the avatar's picture with **Tap to talk**. Select it, allow the microphone, and the avatar greets you and answers when you speak. Keep the `*` in `allow`, or the microphone is blocked. To try it without a page, open [https://www.bithuman.ai/embed/A23WJF0199](https://www.bithuman.ai/embed/A23WJF0199).

The `wise-pup` sample ends each session after 2 minutes. For your site, embed your own agent ([create your own avatar](https://docs.bithuman.ai/build/create-avatar)); its sessions have no such limit.

<div class="fig-end">

*Capture: The sofia-ramirez avatar answering a spoken question in the web embed, in a plain HTML page. Captured on Chrome 154 on Linux · the web embed · sofia-ramirez (Essence 2) · 2026-09-27. The visitor's question is the microphone input, mixed into the recording.* (https://docs.bithuman.ai/examples/web-embed/clip.mp4)

## Performance

Measured in the tab with WebGPU, in Chrome on an Apple M4.

| Configuration | Hardware | Essence 2 | Expression 2 |
|---|---|---|---|
| Web browser (WebGPU) | Chrome on Apple M4 | 1.7× real time | 1.9× real time |
| Web browser (WebGPU) · held 10 min | Chrome on Apple M4 | 2.1× real time | 2.0× real time |

× real time: seconds of video rendered per second; 1.0× or more holds a live conversation ([method](https://docs.bithuman.ai/performance#web)).

## Continue

The rest of this platform, inlined so one fetch covers it: [Build a web app](https://docs.bithuman.ai/platforms/web/app.md) · [Web troubleshooting](https://docs.bithuman.ai/platforms/web/troubleshooting.md).

---

# Build a web app

URL: https://docs.bithuman.ai/platforms/web/app

> Set the embed's URL parameters and fit the avatar into your site.

## Integrate into your app

Add parameters to the URL:

| Parameter | Values | Effect |
|---|---|---|
| `render` | `cloud` (default), `local` | Where the avatar renders: our servers, or the visitor's tab |
| `rendering_mode` | `browser`, `avatar` | Long form of `render=local`; `avatar` renders in the tab with no conversation: an Essence 1 avatar lip-syncs the visitor's own microphone, and an Essence 2 or Expression 2 avatar plays its idle loop |
| `greetingLang` | a language code, for example `es` | Language of the first greeting |
| `greetingMsg` | text | The first thing the avatar says |
| `model` | `essence-2`, `expression-2`, `essence-1`, `expression-1` | Pins the model for this session; it must be in the agent's `supported_models`. Without it, the agent's own model |

A private agent also takes `token` ([Embedding](https://docs.bithuman.ai/api/embedding)). Other parameters are ignored.

### React and other frameworks

There is no npm package: the embed is an iframe in any framework. In React:

```jsx
export function Avatar({ code }) {
  return <iframe src={`https://www.bithuman.ai/embed/${code}`} allow="microphone *" style={{ width: "100%", height: 600, border: 0 }} title="Talking avatar" />;
}
```

For a floating avatar, one script tag adds a widget to any page, Next.js included ([Website widget](https://docs.bithuman.ai/build/website-widget)). The persona and your own model are settings on the agent ([Providers](https://docs.bithuman.ai/api/providers)), so there is no server to run.

To build your own video UI instead of the hosted page, subscribe to a cloud-rendered avatar over [LiveKit](https://docs.bithuman.ai/platforms/livekit).

## Complete example

A whole page with a live avatar: one HTML file and a local web server.

### Requirements

| You need | Notes |
|---|---|
| A current browser | Chrome, Edge, Safari or Firefox |
| A local web server | the page must be served over `http://localhost` or HTTPS for the microphone to work |
| Nothing else | no account for the sample avatar; your own agent works the same way while its Anonymous Share setting is on, and its sessions bill you |

### Get the code

Save this as `index.html`:

```html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>bitHuman web embed</title>
  <style>
    html, body { margin: 0; height: 100%; background: #0f1115; }
    body { display: flex; align-items: center; justify-content: center; }
    iframe { border: 0; border-radius: 16px; }
  </style>
</head>
<body>
  <iframe src="https://www.bithuman.ai/embed/A23WJF0199"
          allow="microphone *; camera *; autoplay *" style="width:100%;height:100vh;border:0"></iframe>
</body>
</html>
```

### Run it

```bash
python3 -m http.server 8765 --bind 127.0.0.1
```

Open `http://127.0.0.1:8765/`. Any free port works: if 8765 is taken, pick another and open that one.

### Expected output

The avatar's picture with **Tap to talk**. Select it and allow the microphone: the avatar greets you within a few seconds. Speak, or type into the **Type or speak…** box, and it answers out loud with its lips in sync. The red button ends the session.

### How it works

The iframe loads the hosted viewer for agent `A23WJF0199`. The viewer opens a real-time session: your microphone audio goes to the agent, and the agent's voice and video come back. `allow="microphone *"` lets the iframe ask for the microphone; without the `*` the browser blocks it. URL parameters are [above](#integrate-into-your-app); session events on [Embedding](https://docs.bithuman.ai/api/embedding).

### Make it your own

- **Your own avatar:** replace `A23WJF0199` with your agent code. Anyone with the code can open it and sessions bill your account; turn off Anonymous Share in the agent's sharing settings to stop that.
- **Push what it says:** from your backend, `POST /v1/agent/{code}/speak` makes a live avatar say a line ([Agents](https://docs.bithuman.ai/api/agents)).
- **Size and layout:** any width and height work; keep roughly a 7:12 portrait shape for Expression 2 avatars.

## Platform notes

- Expression 1 avatars render in the cloud only. For an agent whose own model is Expression 1, add `model=` with another model it supports to render in the tab.
- The in-tab render works for Essence 1, Expression 2, and Essence 2 avatars that have a browser build.
- `render=local` never falls back to the cloud: a device that can't render the avatar in real time shows a message and starts no session ([Render with WebGPU](https://docs.bithuman.ai/platforms/web/webgpu)).

## Reference

- [Embedding](https://docs.bithuman.ai/api/embedding): embed tokens, sizing and private agents.
- [LiveKit](https://docs.bithuman.ai/platforms/livekit): your own UI over a cloud-rendered avatar.
- Examples that need your own LiveKit server and a Python agent (not web embeds): [Next.js front end for a LiveKit agent](https://github.com/bithuman-product/bithuman-examples/tree/main/integrations/nextjs-ui) · [Gradio, a Python app that also needs an OpenAI key](https://github.com/bithuman-product/bithuman-examples/tree/main/integrations/gradio-web).

---

# Web troubleshooting

URL: https://docs.bithuman.ai/platforms/web/troubleshooting

> Fix embed and in-tab rendering problems by symptom.

| Symptom | Cause | Fix |
|---|---|---|
| The microphone never activates | `allow` is missing `microphone *` | use `allow="microphone *"` |
| The frame shows `Agent not found` | the agent code is wrong | copy the code from the agent's Deploy & Share dialog |
| With `render=local`, the frame says "This device can't render this avatar in real time" | no usable WebGPU adapter, or the device measured too slow | use `render=cloud` for that visitor; check `hasRealGPU()` first to choose the mode yourself ([Render with WebGPU](https://docs.bithuman.ai/platforms/web/webgpu)) |
| With `render=local`, the frame says "This avatar can only be rendered in the cloud" | an Expression 1 model | remove `render=local`, or add `model=` with another model the agent supports |
| With `render=local`, the frame says "This avatar can't be rendered in the browser" | the avatar has no browser build | remove `render=local` |
| With `render=local`, the frame says "In-browser rendering is turned off right now" | bitHuman has switched off in-tab rendering for this model | remove `render=local` |
| The iframe shows a browser error page | your page sends `Cross-Origin-Embedder-Policy` | remove that header from the page that holds the iframe |
| A blank frame | a service problem | check [status.bithuman.ai](https://status.bithuman.ai), then reload |
| Your own avatar shows `Embedding is disabled for this agent` | its Anonymous Share setting is off | turn Anonymous Share back on, or keep it off and pass an [embed token](https://docs.bithuman.ai/api/embedding) (`?token=`) |
