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

# Web SDK

> Let visitors talk to your AI agent directly from your website — no phone number, no app download.

## What is the Web SDK?

The Web SDK is a small piece of code you drop into your website. When a visitor clicks a "Talk to us" button, it opens a live voice conversation with your OneInbox agent — right in the browser, using their microphone.

Think of it like a live chat widget, but for voice.

**What it handles for you:**

* Asking the browser for microphone permission
* Streaming audio in real time (both directions)
* Showing live transcripts as the conversation happens
* Mute, unmute, and hang up

**What your team sets up:**

* An agent on OneInbox (the AI that answers)
* A button or widget on your site that starts the call

***

## Quick steps — the simplest way to add it to your site

This is the fastest path: a publishable key + the Web SDK, no backend required.

<Steps>
  <Step title="Create your agent">
    Build the agent that will answer calls — see [Quickstart](/guides/quickstart) if you haven't made one yet. Save its `id` (`agt_…`).
  </Step>

  <Step title="Create a publishable key">
    In the [OneInbox dashboard](https://oneinbox-dashboard.vercel.app), go to **Settings → Publishable Keys** → **Create key**. Enter the allowed origins for this key — one per line:

    | What to enter                                           | When to use                                                                                                       |
    | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
    | `https://yoursite.com`                                  | Restrict the key to a specific domain — requests from any other origin are rejected with `403 ORIGIN_NOT_ALLOWED` |
    | `https://yoursite.com` + `https://staging.yoursite.com` | Multiple specific domains (e.g. production + staging)                                                             |
    | `*` or leave blank                                      | Allow all origins — useful during development or for internal tools where locking to a domain isn't needed        |

    Copy the key — it starts with `oi_pk_live_…`.

    <Warning>
      Using `*` means any website can use your publishable key to start calls on your agent. This is fine for local testing but restrict to your actual domain before going to production.
    </Warning>
  </Step>

  <Step title="Install the Web SDK">
    ```bash theme={null}
    npm install @oneinbox/web-sdk
    ```
  </Step>

  <Step title="Wire it to your agent">
    Initialize the SDK with your publishable key, then point `start()` at your agent's `id`:

    ```ts theme={null}
    import { OneInbox } from "@oneinbox/web-sdk";

    const oi = new OneInbox("oi_pk_live_…");
    await oi.start("agt_…");
    ```
  </Step>

  <Step title="Add a button on your site">
    Wire that `start()` call to any button — e.g. "Talk to us." When a visitor clicks it, the call begins right there in the browser, using their mic.
  </Step>
</Steps>

That's it — no server, no separate "create a call" step. The full event/control API (mute, transcripts, hang up, etc.) is below under [Vanilla example](#vanilla-example) and [React example](#react-example).

***

## How it fits into your product

When a visitor clicks "Call":

1. Your website asks your server: *"start a call for this visitor"*
2. Your server creates the call via the OneInbox API and gets back a short-lived access token
3. The Web SDK uses that token to connect the visitor's browser to the agent
4. The conversation starts — live, two-way voice

Your server holds your secret API key. The browser only ever receives a one-time token that expires when the call ends — so nothing sensitive is exposed to visitors.

***

## Two packages

| Package                   | Use it when                              |
| ------------------------- | ---------------------------------------- |
| `@oneinbox/web-sdk`       | Plain JavaScript or any framework        |
| `@oneinbox/web-sdk-react` | React apps — gives you a ready-made hook |

Both do the same thing. The React package just wraps the core one with React-friendly patterns.

***

## Install

```bash theme={null}
# Vanilla JavaScript / any framework
npm install @oneinbox/web-sdk

# React
npm install @oneinbox/web-sdk-react @oneinbox/web-sdk react
```

Each package is self-contained — the SDK bundles everything it needs to handle the audio connection, so there are no other companion packages to install.

***

## Vanilla example

```ts theme={null}
import { OneInbox } from "@oneinbox/web-sdk";

const oi = new OneInbox("oi_pk_live_…");

// React to what happens during the call
oi.on("call-start",  ()  => showCallUI());
oi.on("call-end",    ()  => showIdleUI());
oi.on("transcript",  (t) => appendTranscript(t.role, t.text));  // live captions
oi.on("error",       (e) => showError(e.message));

// Start the call — pass the visitor's name so the agent greets them
await oi.start("agt_…", { variables: { customer_name: "Sama" } });

// During the call
oi.setMuted(true);   // mute the visitor's mic
oi.setMuted(false);  // unmute

await oi.stop();     // hang up
```

### What you can listen to

| Event                         | What it means                                                         |
| ----------------------------- | --------------------------------------------------------------------- |
| `call-start`                  | The call connected — show your active call UI                         |
| `call-end`                    | The call ended — return to idle state                                 |
| `transcript`                  | A new line of speech was heard — update captions or a chat log        |
| `speech-start` / `speech-end` | Someone started or stopped speaking — animate a speaking indicator    |
| `volume-level`                | How loud the visitor's mic is right now (0–1) — drive a mic level bar |
| `error`                       | Something went wrong — show an error message                          |

### Controls

| Method                             | What it does                                               |
| ---------------------------------- | ---------------------------------------------------------- |
| `oi.start(agentId, { variables })` | Start the call                                             |
| `oi.stop()`                        | End the call                                               |
| `oi.setMuted(true / false)`        | Mute or unmute the visitor's mic                           |
| `oi.isMuted()`                     | Returns `true` if the mic is currently muted               |
| `oi.status`                        | Current state: `idle`, `connecting`, `active`, or `ending` |

***

## React example

```tsx theme={null}
import { OneInboxProvider, useOneInbox } from "@oneinbox/web-sdk-react";

// Wrap your app once at the top level
function App() {
  return (
    <OneInboxProvider publishableKey="oi_pk_live_…">
      <CallWidget agentId="agt_…" />
    </OneInboxProvider>
  );
}

// Use the hook anywhere inside the provider
function CallWidget({ agentId }) {
  const { start, stop, status, transcripts, isAgentSpeaking, isMuted, setMuted } = useOneInbox();
  const active = status === "active";

  return (
    <div>
      <button onClick={() => (active ? stop() : start(agentId))}>
        {active ? "Hang up" : "Talk to us"}
      </button>

      {active && (
        <button onClick={() => setMuted(!isMuted)}>
          {isMuted ? "Unmute" : "Mute"}
        </button>
      )}

      <p>{isAgentSpeaking ? "Agent is speaking…" : status}</p>

      {transcripts.map((t, i) => (
        <p key={i}><b>{t.role}:</b> {t.text}</p>
      ))}
    </div>
  );
}
```

`useOneInbox()` gives you everything you need to build a call UI:

| Value                         | What it is                                                    |
| ----------------------------- | ------------------------------------------------------------- |
| `status`                      | Current call state (`idle`, `connecting`, `active`, `ending`) |
| `transcripts`                 | Every line of the conversation so far                         |
| `isAgentSpeaking`             | `true` while the agent is talking                             |
| `isMuted`                     | `true` if the visitor's mic is muted                          |
| `volume`                      | Mic level in real time (0–1)                                  |
| `error`                       | The last error, if any                                        |
| `start` / `stop` / `setMuted` | Controls                                                      |
