Dialerr Embed documentation

Embed a full softphone — calls, SMS, voicemail — into your own website or app, as a floating widget or inline as a column of the page. Your agents dial from your pages; you sign them in from your backend with a minted token, so agents don't need per-seat vendor accounts or a separate login.

Keys Script tag Inline mode React CLI MCP (AI assistants) Token route Widget config JS API HTTP API Security Troubleshooting

Keys

Create a key at dialerr.com → Settings → API Access → “Embed the toolbar on your site”. You get:

Restrict each key to your domains (wildcards like https://*.example.com supported). Tokens are only minted for allowlisted origins. No dashboard needed: the CLI and MCP server can provision a key via a browser-approved device flow.

Install — script tag (recommended)

Nothing to install or run. Add before </body>; the widget runs in a sandboxed iframe served from dialerr.com:

<script src="https://dialerr.com/embed.js" data-key="pk_live_xxx"></script>

That alone works — agents sign into Dialerr inside the widget. For automatic sign-in add your token route:

<script src="https://dialerr.com/embed.js" data-key="pk_live_xxx" data-token-url="/api/dialerr/token"></script>

The tag also works with no data-key: agents then sign in inside the widget. A key is what enables automatic sign-in and the domain allowlist.

Inline mode — the dialer as part of the page

data-mode="inline" renders the full dialer (dial pad, messages, leads, calls, notifications — the same column the Dialerr dashboard shows) inside an element you own, at whatever size you give it. Nothing floats and there is no launcher. It is built for a CRM or back office where people keep the dialer open all day.

<div id="dialerr" style="width: 440px; height: 100vh;"></div>
<script src="https://dialerr.com/embed.js" data-mode="inline" data-target="#dialerr"></script>

Check it works: an iframe whose src starts with https://dialerr.com/dashboard?embed=inline sits inside your element; the console has no [Dialerr] lines; window.Dialerr.mode is "inline"; dialerr:ready fires on window; a call placed from the panel prompts for the microphone once and fires dialerr:call_connected then dialerr:call_ended; and window.Dialerr.startCall('+15551234567', 'Test Lead') from your page makes the panel dial.

Install — React / bundlers

npm i @dialerr/embed
import { DialerrToolbar } from '@dialerr/embed/react';
// render once near the app root:
<DialerrToolbar dataKey="pk_live_xxx" tokenUrl="/api/dialerr/token" />

Programmatic: import { init, on, startCall } from '@dialerr/embed'.

Install — CLI

npx @dialerr/cli add              # no key? opens a browser to provision one
npx @dialerr/cli add --key pk_...  # already have a key
npx @dialerr/cli login             # provision + print keys, change nothing

Detects Next.js / Vite / CRA / plain HTML, injects the widget, scaffolds the Next.js token route, writes .env.local. Flags: --dry-run, --framework, --token-url, --base. The CLI only reads your project and writes local files. The secret key is never a CLI argument.

Install — MCP server (AI coding assistants)

claude mcp add dialerr -- npx -y @dialerr/mcp
{ "mcpServers": { "dialerr": { "command": "npx", "args": ["-y", "@dialerr/mcp"] } } }

Then ask your assistant to “add a phone dialer with Dialerr.” Tools: dialerr_get_install_guide, dialerr_start_key_provisioning (gives the user a browser link to approve — sign-in or account creation happens there), and dialerr_check_key_provisioning (returns the keys once). The server only calls the dialerr.com API — it reads no files and runs no commands.

Seamless sign-in — the token route

Your backend exchanges the secret key for a short-lived agent token (~30 min); the widget re-mints automatically.

// Next.js — app/api/dialerr/token/route.ts
export async function GET() {
  const r = await fetch('https://dialerr.com/api/v1/embed/token', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.DIALERR_SECRET}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({}), // or { agentEmail: currentUser.email }
    cache: 'no-store',
  });
  return new Response(await r.text(), { headers: { 'content-type': 'application/json' } });
}

Widget configuration

AttributeMeaningDefault
data-keyPublishable key — recommended; without it agents sign in inside the widget—
data-surfacetoolbar (compact softphone) or dialer (the full dialer: calls, messages, leads, notifications) — what the launcher opensyour account's Embedded widget setting
data-modefloating (launcher in the corner) or inline (the full dialer rendered inside an element you own)floating
data-targetCSS selector of the slot for inline mode, e.g. #dialerr—
data-token-urlYour mint route for seamless sign-innone (in-widget login)
data-positionfloating: bottom-right / bottom-leftbottom-right
data-colorfloating: launcher color#4f46e5
data-width / data-heightfloating: panel width / max height in px400 / 640 (toolbar), 440 / 960 (dialer)
data-auto-openfloating: true opens the panel on loadfalse
data-baseToolbar originscript's origin

JavaScript API

Events (also DOM events dialerr:<event> on window): ready, open, close, mode_changed, mode_change_refused, call_connected, call_ended, missed_call, sms_received, voicemail, lead_dispositioned, auth_invalid.

HTTP API

EndpointAuthPurpose
POST /api/v1/embed/tokenBearer sk_… (server)Mint a ~30-min agent token. Body: { agentId } or { agentEmail } (optional; falls back to the key's default agent). Origin-bound; 30/min rate limit.
GET /api/v1/embed/config?key=pk_…publicValidate a key → { name, orgName, allowedOrigins }.
POST /api/v1/embed/device/codenoneStart device flow → { deviceCode, userCode, verificationUriComplete, … } (10-min expiry).
POST /api/v1/embed/device/tokennonePoll with { deviceCode } → pending, then once: { publicKey, secretKey }. 410 after claim/expiry.

Security

Troubleshooting

AI assistant? The machine-readable version of this page is dialerr.com/llms.txt — it contains everything needed to complete an install end-to-end.