# Widget Integration

> Embed a fully interactive Human Agent on your website with a single HTML tag.

## Quick Start

Add the Ojin widget script to your page and drop in the agent tag:

```html
<script src="https://widget.ojin.ai/ojin-agent.js"></script>
<ojin-agent agent-id="your-agent-id"></ojin-agent>
```

{% hint style="info" %}
The widget script URL is available in your agent's settings page in the [dashboard](https://ojin.ai/dashboard). Copy it from there to ensure you're using the latest version.
{% endhint %}

That's it. Your users get a live conversational agent with video, audio, and a real-time avatar — no backend code required.

## Appearance & Layout

The widget renders as a floating overlay on your page. It includes the avatar video feed, audio controls, and session management — all self-contained.

{% hint style="info" %}
Widget styling and positioning options are configured in your agent's settings in the [dashboard](https://ojin.ai/dashboard). Check your agent's widget configuration for available customization options.
{% endhint %}

## Finding Your Agent ID

After [creating and configuring your agent](/apps/overview/configure.md), copy the agent ID from the agent settings page in the [Ojin dashboard](https://ojin.ai/dashboard).

## Controlling Access

Agents are **private by default** — connections from any website are rejected until you configure access.

### Hostname Allowlist

In the [dashboard](https://ojin.ai/dashboard), add the domains that are allowed to connect to your agent:

| Configuration                    | Behaviour                                           |
| -------------------------------- | --------------------------------------------------- |
| No hostnames configured          | **Private** — all connections rejected              |
| `myapp.com`, `staging.myapp.com` | Only requests from those exact domains are accepted |
| `*`                              | **Public** — connections accepted from any domain   |

{% hint style="warning" %}
Using `*` (wildcard) allows anyone to connect to your agent. This is useful for demos but not recommended for production. Use specific hostnames to restrict access to your own domains.
{% endhint %}

{% hint style="info" %}
No API key is needed in the widget. Access is controlled entirely by the hostname allowlist — the server checks the request's origin against your configured domains.
{% endhint %}

## How It Works

When the widget loads on your page:

1. The widget calls the Session API (`POST /v1/public/agents/connect`) with your agent ID
2. The server validates the request origin against the hostname allowlist
3. On success, the server returns a WebRTC room URL and token
4. The widget connects to the WebRTC room directly
5. Audio, video, and signaling all flow over a single WebRTC connection

The entire handshake takes a few seconds. After that, your user is in a live conversation with the agent.

## Custom Integrations

If you need more control than the widget provides — for example, building a native mobile app or a custom web experience — you can call the Session API directly from your backend and connect to the WebRTC room yourself.

See the [Session API Reference](/apps/overview/api-reference.md) for details.

## Troubleshooting

### Widget not loading

* Verify the widget script URL is correct and the script loads without errors (check browser console)
* Confirm the `agent-id` attribute matches your agent's ID in the dashboard

### "agent\_offline" error

* Check that your agent's status is set to **online** in the [dashboard](https://ojin.ai/dashboard)
* Ensure all required fields are filled — the dashboard won't let you go online with missing configuration

### "auth\_failed" error

* Verify your domain is in the agent's hostname allowlist in the [dashboard](https://ojin.ai/dashboard)
* Check that the `Origin` header sent by the browser matches one of your configured hostnames exactly
* If testing locally, add `localhost` or `127.0.0.1` to the allowlist

### "concurrency\_limit" error

* Your agent's maximum concurrent sessions are in use. Wait for an active session to end or increase the **max concurrency** setting in the dashboard

### No audio or video

* Ensure the user's browser has granted microphone and camera permissions
* Check that the WebRTC connection is not blocked by a firewall or corporate proxy


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ojin.ai/apps/overview/widget-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
