Building Blocks / CRM Workspace
The Dock (one widget)
One widget for a CRM: click a contact, dial, text, and open inbox.
Drop-in widget. Load
https://webforms.dropcowboy.com/latest/dropcowboy-dock.min.jsand pass it a site token your server mints. Do not rebuild WebRTC calling, the inbox, or the contact panel; the widget already does it.Calling setup comes with the site token. Your page never configures SIP, STUN, or TURN servers; the script does.
When to use this vs REST
Use the Dock when agents work inside your CRM and need to dial, text, and see the inbox without leaving it. Use REST when no person is at a screen, for example sending a follow-up text from a job.
Do not rebuild
- A softphone, call controls, or audio device handling.
- The unified inbox or contact side panel.
- Caller ID selection. Local presence picks the number.
Drop-in
- On your server, trade your API key for a short-lived site token (the key needs
numbers:write):
// Your server. Browser code never sees KEY/SECRET.
app.post('/dropcowboy/token', async function (req, res) {
const r = await fetch('https://api-v2.dropcowboy.com/phone/public/embed/token', {
method: 'POST',
headers: {
'x-key': process.env.DC_KEY,
'x-secret': process.env.DC_SECRET,
'Content-Type': 'application/json'
},
body: JSON.stringify({ site_id: process.env.DC_SITE_ID, scope: ['dialer:webrtc', 'contacts'], ttl_seconds: 900 })
});
const body = await r.json();
if (!r.ok) return res.status(r.status).json(body);
// The API wraps results in data. Hand the browser just the token.
res.json({ token: body.data.token, expires_at: body.data.expires_at });
});
Or test the mint with cURL:
# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.
curl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \
-H "x-key: $KEY" -H "x-secret: $SECRET" \
-H "Content-Type: application/json" \
-d '{"site_id":"YOUR_SITE_ID","scope":["dialer:webrtc","contacts"],"ttl_seconds":900}'
- Load the script, init with the token, and call a method:
<script src="https://webforms.dropcowboy.com/latest/dropcowboy-dock.min.js"></script>
<script>
(async function () {
const minted = await fetch('/dropcowboy/token', { method: 'POST' }).then(function (r) { return r.json(); });
await DropCowboy.dock.init({
token: minted.token,
mode: 'floating',
panes: ['dialer', 'inbox', 'contacts']
});
DropCowboy.dock.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });
DropCowboy.dock.addPaneChangeListener(function (event) {
console.log('dock pane', event.pane);
});
document.getElementById('contacts').addEventListener('click', function (e) {
var row = e.target.closest('[data-contact-id]');
if (!row) return;
DropCowboy.dock.dial({
contact: {
id: row.getAttribute('data-contact-id'),
name: row.getAttribute('data-name'),
phone: row.getAttribute('data-phone')
}
});
});
})();
</script>
JS API / HTML tag
| Method | What it does |
|---|---|
init({ token, mode, dockRole, partnerName, panes }) |
Mounts the dock. mode is 'floating', 'pinned', or 'fill'. panes is dialer, messages, inbox, contacts, pipeline, campaigns. |
setTheme({ theme, primaryColor }) |
Applies LIGHT/DARK and your accent color to every pane. |
dial({ contact, container }) |
Opens the dialer pane and preloads the contact. contact needs id, name, phone. |
open(pane, { contact, container }) |
Opens a specific pane. Same contact shape as dial(). |
setMode('floating' | 'pinned' | 'fill') |
Changes layout at runtime. |
setPanes([pane, ...]) |
Shows or hides nav items. If the active pane is removed, the dock switches to the first remaining pane. |
addPaneChangeListener(fn) -> stop |
Fires { pane } on nav clicks and open()/dial()/setPanes(). |
addDockToggleListener(fn) -> stop |
Fires { open } when the dock expands or minimizes. |
close() |
Minimizes the dock and drops the session token. |
HTML tag:
<dc-dock mode="floating" panes="dialer,inbox,contacts" open></dc-dock>
Auth and scopes
Site token. Your API secret stays on your server.
Site token scope: dialer:webrtc contacts. Mint it with POST https://api-v2.dropcowboy.com/phone/public/embed/token using an API key with numbers:write. Tokens last up to one hour.
Limits
- Site tokens last at most one hour (the default). Mint a fresh one per page load or session; do not cache one across users.
- Calls and texts need a connected carrier (BYOC) and prepaid balance. Without them the mint returns 402 or 403 for telephony scopes.
Related REST
Routes are on https://api-v2.dropcowboy.com.
- POST /phone/public/embed/token - mint the site token
- POST /sms - send a text from your server
- GET /contact/public/contacts - look up contacts
Full reference: Embed site tokens, Texts API, Contacts API.