Build calling, messaging and voice AI into your product
Three ways in: drop ready-made UI into your app, send outreach over a REST API, or build on the same voice intelligence that powers Drop Cowboy®.
REST base URL: https://api-v2.dropcowboy.com
Pick your door
Each one works on its own. Most teams end up using two.
Building Blocks
- One script tag plus a short-lived token from your server
- Softphone, inbox, contacts and texting registration panes
- Branded to your product
REST outreach
- API key pair or OAuth client credentials
- Calling-hour and contact frequency checks on every send
- Every outcome has a documented reason code
Voice Intelligence
- Detection at wss://detect.dropcowboy.com/carrier/ws
- Agents answer from your knowledge bases
- Receptionist answers on your own number
See it in code
Real requests against the live API. Set DC_KEY and DC_SECRET to your API key pair.
// Your server. Browser code never sees KEY/SECRET. The key needs numbers:write.
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 })
});
res.status(r.status).json(await r.json());
});<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']
});
})();
</script>curl -X POST https://api-v2.dropcowboy.com/rvm \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"to": "+13125550142",
"phone_line_id": "e2b6f9a3-5c1d-4e8b-a4f7-9c3e1b5d7a28",
"media_id": "1b7e3c9a-4d2f-4a8b-9e6c-7f2a1d5b3c80",
"foreign_id": "order-1042"
}'curl -X POST https://api-v2.dropcowboy.com/sms \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"to": "+13125550142",
"phone_line_id": "e2b6f9a3-5c1d-4e8b-a4f7-9c3e1b5d7a28",
"body": "Your order is ready for pickup. Reply STOP to opt out.",
"foreign_id": "order-1042"
}'curl -X POST https://api-v2.dropcowboy.com/email/public/email \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"to": [{ "address": "jordan.rivera@example.com", "name": "Jordan Rivera" }],
"mailbox_id": "c5f1a8d3-6e2b-4c9f-b1a7-8d4e2c6f9b35",
"subject": "Your order is ready",
"html": "<p>Hi Jordan, your order is ready for pickup.</p>"
}'// npm install ws. The Detection API key comes from support; keep it server-side.
const WebSocket = require('ws');
const ws = new WebSocket('wss://detect.dropcowboy.com/carrier/ws', {
headers: { Authorization: 'Bearer ' + process.env.DETECTION_API_KEY }
});
ws.on('open', () => {
ws.send(JSON.stringify({
type: 'welcome',
payload: {
call_id: '4e8c2a6d-1f9b-4d3e-a5c7-2b6f8d4a9e31',
audio_encoding: 'pcm16',
sample_rate_hz: 8000,
strategy: 'standard'
}
}));
});
ws.on('message', (data, isBinary) => {
if (isBinary) return;
const msg = JSON.parse(data.toString());
if (msg.event === 'ready') {
// Start sending the call audio as binary frames, in real time.
}
if (msg.event === 'detection' && msg.payload.is_final) {
console.log('answered by', msg.payload.type);
}
if (msg.event === 'beep') {
// The beep ended: start your message now.
}
});
// When the call ends:
// ws.send(JSON.stringify({ command: 'stop' }));curl https://api-v2.dropcowboy.com/voice/public/tts/synthesize \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"voice_id": "7d2a9e4b-1c6f-4b3a-8e5d-2f9c7a1b4e63",
"text": "Thanks for calling Example Dental. How can I help?"
}'# 1. A knowledge base the agent answers from (then add documents to it)
curl -X POST https://api-v2.dropcowboy.com/document/public/knowledge-bases \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "name": "Customer FAQ", "description": "Hours, pricing and service area for callers.", "ai_audience": "public" }'
# 2. An agent from an inbound template. Attach the knowledge base in
# think.knowledge (see /developers/api/agents), then publish.
curl -X POST https://api-v2.dropcowboy.com/agents/public/agents/from-template \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "template_id": "inbound-appointment-setting", "name": "Front desk", "active": true }'
curl -X POST https://api-v2.dropcowboy.com/agents/public/agents/$AGENT_ID/publish \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
# 3. A phone line whose rules send calls to the agent (line.json:
# see /developers/api/agents/ai-receptionist), then assign your number.
curl -X POST https://api-v2.dropcowboy.com/phone/public/lines \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d @line.json
curl -X POST https://api-v2.dropcowboy.com/phone/public/lines/$LINE_ID/assign \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "number": "+13125550142" }'Your first request in three steps
Create an API key
In the dashboard, open Developers and create a key pair with the scopes you need. Send it as the x-key and x-secret headers.
Subscribe to results
A send answers 202 when it is accepted. Subscribe to the status webhook for each channel so you learn the result of each send.
Send to yourself
Add your own numbers as test numbers on the Dialing rules page. They skip the contact frequency limit while you build.
OpenAPI spec and Postman collection
Generate a client from the spec, or try every route from Postman before you write any code.
OpenAPI spec
The machine-readable contract for every route, in OpenAPI 3.1. Load it into a code generator or any tool that reads OpenAPI. No credentials needed.
Postman collection
Every route as a ready-to-send request, plus an environment for your API key pair. Download the files or import them by address.
Reference and guides
API reference
Every route, grouped by what you are building.
Quickstart
From a new key to your first send and its result.
Webhooks
Subscribe to events, verify signatures and track the result of every send.
SDKs and libraries
Every feature is a plain HTTPS request, so the HTTP client you already use is all you need.
Outcomes and what to do
Every reason_code a send can report, what it means, and what to do next.
Troubleshooting
A send did not arrive, a webhook is missing, or a voicemail has no audio: start here.
Canvas widgets
Add your own panel to the Drop Cowboy dashboard. Your server answers a signed request with Canvas JSON.
MCP for AI tools
Connect Cursor, VS Code, Claude and other MCP clients to your account.
Changelog
What changed in the API and these docs, and how the API is versioned.
Developer questions
How do I authenticate?
Does a 202 mean my message was delivered?
What happens outside calling hours?
Why did a send fail with 4013?
Which HTTP client should I use?
How do opt-outs work?
How do I get a Detection API key?
Building something bigger?
Talk to us about volume, dedicated numbers, or embedding Drop Cowboy in your platform.