> ## Documentation Index
> Fetch the complete documentation index at: https://docs.protoface.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Embeds

> Share links, iframes, and custom UIs for live conversations.

Embeds let visitors talk to a ready avatar, custom or stock. Protoface
hosts the conversation, so there is no agent to build and no API key on
the page, only a public embed ID.

All three options share the same settings, credits, and limits.

| Option | What it does |
| - | - |
| Share link | Opens a Protoface-hosted page you can send to anyone. |
| iframe embed | Puts the avatar on a page of your site. |
| Custom UI | Wraps the conversation in your own interface with `protoface-client`. |

## Default embed

Every ready avatar has a default embed, enabled on any origin until
restricted.

1. Open **Avatars** in the [dashboard](https://app.protoface.com).
2. Select a ready avatar, then **Embed**.
3. Find the default embed under **Current Embed**.

That panel sets the intro, placement, conversation limits, and domain
restrictions. Voice and instructions live on the avatar under **Avatar
Settings** and apply everywhere it is used.

## Additional embeds

**New Embed** creates a second configuration for another site,
environment, or campaign. It starts enabled, with domain restrictions
off.

To restrict it, open **Advanced Options**, turn on **Domain
Restrictions**, and add origins under **Allowed Website Origins**. An
origin is scheme, host, and optional port. Paths, query strings,
fragments, and wildcards are rejected.

| Accepted | Rejected |
| - | - |
| `https://acme.com` | `https://acme.com/products` |
| `https://app.acme.com` | `https://acme.com/*` |
| `http://localhost:3000` | `*.acme.com` |

One origin per line. Each domain and subdomain is separate, so
`https://acme.com` does not allow `https://www.acme.com`.

With restrictions off, the embed works on any website, which is
convenient while testing. Restrict production embeds to the origins you
actually use.

## Share link

The share link in the Embed panel opens a Protoface-hosted page. Nothing
is added to your site.

## iframe embed

Copy **Embed Code** from the panel:

```html theme={null}
<protoface-avatar embed-public-id="emb_..."></protoface-avatar>
<script src="https://app.protoface.com/embed-widget.js" async></script>
```

Set **Placement** before copying. The placement saves on the embed, so it
applies anywhere you use that ID. **Inline** sits in document flow. The
four corner placements stay visible as visitors scroll.

An inline embed fills the available width, and the snippet carries an
aspect ratio taken from the portrait. Override either with CSS.

```css theme={null}
protoface-avatar {
  width: min(100%, 720px);
  aspect-ratio: 16 / 9;
}
```

### Embed events

The `<protoface-avatar>` element dispatches browser events as the
conversation progresses, which you can use to update your own page. They
report state and do not control it, and the embed works whether or not
you listen.

```html theme={null}
<p id="avatar-status">Ready to talk</p>

<script>
  const avatar = document.querySelector("protoface-avatar");
  const status = document.querySelector("#avatar-status");

  avatar.addEventListener("protoface-avatar:conversation-started", () => {
    status.textContent = "Conversation started";
  });

  avatar.addEventListener("protoface-avatar:ended", () => {
    status.textContent = "Conversation ended";
  });
</script>
```

Listen on the element or a parent. `detail` carries the payload.

| Event | When | Useful `detail` |
| - | - | - |
| `protoface-avatar:config-loaded` | Settings finished loading | `enabled`, `avatarName`, `placement` |
| `protoface-avatar:consent-changed` | Consent checkbox changed | `checked` |
| `protoface-avatar:conversation-started` | Conversation created | `room`, `expiresAt` |
| `protoface-avatar:live` | Conversation connected | `room` |
| `protoface-avatar:transcript` | Visitor or avatar speech (may fire more than once) | `role`, `content`, `final` |
| `protoface-avatar:ended` | Conversation ended | `reason`, `failed` |
| `protoface-avatar:error` | The embed cannot complete an action | `code`, `message` |
| `protoface-avatar:closed` | Visitor hides a corner embed | `reason` |
| `protoface-avatar:reopened` | Visitor reopens a corner embed | none |

On transcripts, `role` is either `user` or `agent`, and `final` is `true`
once that part of the transcript is complete. `room` identifies the
individual conversation.

## Custom UI

With `protoface-client`, you own consent, controls, placement,
transcripts, errors, and status in your own layout. Start from the
[conversations quickstart](https://github.com/protoface-ai/protoface-quickstart-conversations)
and swap in the public ID from the Embed panel.

The frontend needs nothing beyond that ID. Embed settings and account
limits still apply server-side.

## What visitors see

The iframe and share link show the portrait and intro, then consent and
microphone access. A custom UI presents the same steps in its own design.
Visitors can end a conversation at any time, and the hosted UIs explain a
disabled embed, an exhausted limit, or an outage.

## Access and limits

Every conversation spends the embed owner's credits and counts against
their concurrent-session limit.

| Control | Effect |
| - | - |
| Deactivate | Stops new conversations, keeps settings |
| Regenerate Link | Issues a new public ID, breaking existing iframe embeds, custom UIs, and share links |
| Starts per Hour | Caps new conversations on the embed |
| Active per Visitor | Caps simultaneous conversations per visitor |
| Max Seconds | Ends a conversation after the set time, up to 3,600 seconds |

## Troubleshooting

| Symptom | Check |
| - | - |
| Avatar does not appear | Embed is enabled. If domain restrictions are on, the page origin is in **Allowed Website Origins**. |
| Avatar cannot hear the visitor | Browser microphone permission for this origin, then reload. |
| Conversation does not start | **Starts per Hour**, **Active per Visitor**, and the account credit balance. |
| Old links 404 | The public ID was regenerated. Open **Avatars**, select **Embed**, and copy the current share link or embed code. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.