{"blocks":[{"id":"dock","name":"The Dock (one widget)","category":"workspace","kind":"widget","status":"available","package":"JavaScript","summary":"One widget for a CRM: click a contact, dial, text, and open inbox.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"<script src=\"https://webforms.dropcowboy.com/latest/dropcowboy-dock.min.js\"></script>\n// getToken asks your server for a fresh site token. The Dock calls it before expiry and once after a 401.\nfunction getToken() { return fetch('/dropcowboy/token', { method: 'POST' }).then(function (r) { return r.json(); }).then(function (b) { return b.token; }); }\nawait DropCowboy.dock.init({ token: await getToken(), getToken: getToken, from: '+15125550100', mode: 'floating', panes: ['dialer', 'messages', 'inbox', 'contacts'] });\nDropCowboy.dock.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nDropCowboy.dock.setContact({ contact_id: '6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f' });\nDropCowboy.dock.dial({ contact_id: '6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f' });\nDropCowboy.dock.text('+15125550148');\nconst stop = DropCowboy.dock.addCallEndedListener(function (event) {});\nDropCowboy.dock.addErrorListener(function (event) {});\nDropCowboy.dock.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\",\"contacts\"],\"ttl_seconds\":900}'","html":"<dc-dock mode=\"floating\" panes=\"dialer,messages,inbox,contacts\" contact-id=\"6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f\" from=\"+15125550100\" open></dc-dock>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/dock","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/dock.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/dock/SKILL.md"},{"id":"chat","name":"Web Chat","category":"conversations","kind":"loader","status":"available","package":"dropcowboy-loader (live)","summary":"Visitor chat on your site, with handoff to SMS or a live call.","deliveryModes":["Loader script (live)","Hosted iframe"],"transports":["Loader script"],"auth":"Site-scoped chat_site_id via data-messenger-id (Origin enforced)","snippets":{"script":"<script src=\"https://webforms.dropcowboy.com/latest/dropcowboy-loader.min.js\"\n        data-messenger-id=\"YOUR_CHAT_SITE_ID\"\n        defer></script>\n<script>document.addEventListener('DOMContentLoaded', function () { DropCowboy.chat.open(); });</script>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/chat","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/chat.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/chat/SKILL.md"},{"id":"messenger","name":"Messenger (SMS/MMS/RCS)","category":"conversations","kind":"widget","status":"available","package":"JavaScript","summary":"Two-way SMS from your app, sent from your business number.","deliveryModes":["JavaScript","iOS and Android apps"],"transports":["JavaScript","iOS","Android"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"<script src=\"https://webforms.dropcowboy.com/latest/dropcowboy-messenger.min.js\"></script>\nawait DropCowboy.messenger.init({ token: SITE_TOKEN, from: '+15125550100' });\nDropCowboy.messenger.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nawait DropCowboy.messenger.sendMessage('+15125550148', { body: 'Hi from Drop Cowboy' });\nconst stop = DropCowboy.messenger.addMessageListener(function (event) {});\nDropCowboy.messenger.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/messenger","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/messenger.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/messenger/SKILL.md"},{"id":"shared-inbox","name":"Shared Inbox","category":"conversations","kind":"widget","status":"available","package":"JavaScript","summary":"One inbox for texts, chat, voicemail, and calls.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.inbox.init({ token: SITE_TOKEN, from: '+15125550100' });\nDropCowboy.inbox.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nDropCowboy.inbox.openInbox();\nconst stop = DropCowboy.inbox.addErrorListener(function (event) {});\nDropCowboy.inbox.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'","html":"<dc-shared-inbox from=\"+15125550100\"></dc-shared-inbox>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/shared-inbox","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/shared-inbox.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/shared-inbox/SKILL.md"},{"id":"dialer","name":"Dialer / Softphone","category":"voice","kind":"widget","status":"available","package":"JavaScript","summary":"Softphone in the browser. Click a contact, place the call.","deliveryModes":["JavaScript","iOS and Android apps"],"transports":["JavaScript","iOS","Android"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"<script src=\"https://webforms.dropcowboy.com/latest/dropcowboy-dialer.min.js\"></script>\nawait DropCowboy.dialer.init({ token: SITE_TOKEN });\nDropCowboy.dialer.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nDropCowboy.dialer.callPhone('+15125550148');\nconst stop = DropCowboy.dialer.addCallEndedListener(function (event) {});\nDropCowboy.dialer.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/dialer","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/dialer.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/dialer/SKILL.md"},{"id":"receptionist","name":"AI Receptionist","category":"voice","kind":"widget","status":"available","package":"JavaScript","summary":"Let visitors talk to your AI agent from your app.","apiDocUrl":"https://www.dropcowboy.com/developers/api/agents/ai-receptionist","deliveryModes":["JavaScript","iOS and Android apps"],"transports":["JavaScript","iOS","Android"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"<script src=\"https://webforms.dropcowboy.com/latest/dropcowboy-receptionist.min.js\"></script>\nawait DropCowboy.receptionist.init({ token: SITE_TOKEN, agentId: 'a9c3e8f1-4b2d-4a7c-8e9b-1c2d3e4f5a6b' });\nDropCowboy.receptionist.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nawait DropCowboy.receptionist.startSession();\nconst stop = DropCowboy.receptionist.addSessionEndedListener(function (event) {});\nDropCowboy.receptionist.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/receptionist","api_doc_url":"https://www.dropcowboy.com/developers/api/agents/ai-receptionist","doc_path":"v2/docs/embed/building-blocks/receptionist.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/receptionist/SKILL.md"},{"id":"phone-hub","name":"Phone Hub (Inbound)","category":"voice","kind":"widget","status":"available","package":"JavaScript","summary":"Pick a number, set hours, and route inbound calls.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token with the phone hub scope. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.phoneHub.init({ token: SITE_TOKEN });\nDropCowboy.phoneHub.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nDropCowboy.phoneHub.openNumberPicker();\nconst stop = DropCowboy.phoneHub.addErrorListener(function (event) {});\nDropCowboy.phoneHub.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"phone:hub\"],\"ttl_seconds\":900}'","html":"<dc-phone-hub></dc-phone-hub>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/phone-hub","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/phone-hub.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/phone-hub/SKILL.md"},{"id":"detection","name":"Detection (AMD / Beep / Screening)","category":"voice","kind":"api","status":"available","package":"Carrier WebSocket","summary":"Person, machine, or beep, on our dialer or your carrier.","apiDocUrl":"https://www.dropcowboy.com/developers/api/detection","deliveryModes":["Carrier WebSocket","Twilio Media Streams","Webhook"],"transports":["WebSocket","TwiML","Webhook"],"auth":"Detection API key, server-side only. Send it as Authorization: Bearer on the WebSocket upgrade, or as <Parameter name=\"api_key\"> on a Twilio <Stream>. No site token.","authException":true,"snippets":{"websocket":"const WebSocket = require('ws');\nconst ws = new WebSocket('wss://detect.dropcowboy.com/carrier/ws', {\n  headers: { Authorization: 'Bearer ' + process.env.DETECTION_API_KEY }\n});\nws.on('open', () => ws.send(JSON.stringify({\n  type: 'welcome',\n  payload: { call_id: 'a9c3e8f1-4b2d-4a7c-8e9b-1c2d3e4f5a6b', audio_encoding: 'pcm16', sample_rate_hz: 8000, strategy: 'standard' }\n})));\n// After the ready event, send 20 ms binary frames of 8 kHz mono PCM16 audio.\nws.on('message', (data, isBinary) => {\n  if (isBinary) return;\n  const ev = JSON.parse(data.toString());\n  if (ev.event === 'detection') routeOn(ev.payload.type, ev.payload.confidence);\n  if (ev.event === 'beep') startVoicemailPlayback();\n});","twiml":"<Response>\n  <Start>\n    <Stream url=\"wss://detect.dropcowboy.com/carrier/ws/twilio\" track=\"inbound_track\">\n      <Parameter name=\"api_key\" value=\"YOUR_DETECTION_API_KEY\"/>\n      <Parameter name=\"webhook_url\" value=\"https://hooks.example.com/detection\"/>\n      <Parameter name=\"webhook_events\" value=\"beep,detection,close\"/>\n    </Stream>\n  </Start>\n  <Dial>+15125550148</Dial>\n</Response>","webhook":"// Mount with express.raw({ type: 'application/json' }) so req.body is the raw bytes.\nconst crypto = require('crypto');\nfunction verifyDetectionWebhook(req) {\n  const ts = req.get('X-Timestamp');\n  const sig = req.get('X-Signature') || '';\n  if (!ts || Math.abs(Date.now() - Number(ts)) > 5 * 60 * 1000) return false;\n  const expected = 'v1=hmac-sha256,' + crypto.createHmac('sha256', process.env.DETECTION_API_KEY)\n    .update(ts + '.' + req.body).digest('hex');\n  const a = Buffer.from(sig);\n  const b = Buffer.from(expected);\n  return a.length === b.length && crypto.timingSafeEqual(a, b);\n}"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/detection","api_doc_url":"https://www.dropcowboy.com/developers/api/detection","doc_path":"v2/docs/embed/building-blocks/detection.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/detection/SKILL.md"},{"id":"tts","name":"Text-to-Speech","category":"voice","kind":"api","status":"available","package":"REST","summary":"Turn text into a recording with a stock or cloned voice.","apiDocUrl":"https://www.dropcowboy.com/developers/api/voice#text-to-speech","deliveryModes":["Server request","Browser request with a site token"],"transports":["REST","TwiML"],"auth":"API key and secret on your server (voice:send). From a browser, send Authorization: Bearer with a site token minted with the voice scope.","snippets":{"curl":"curl -X POST https://api-v2.dropcowboy.com/voice/public/tts/synthesize \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Hello from Acme\",\"voice_id\":\"e2b7c9d4-3f1a-4c8e-9b6d-7a5f0e1c2d3b\"}'","twiml":"const VoiceResponse = require('twilio').twiml.VoiceResponse;\n\napp.post('/twilio/voice', async function (req, res) {\n  const audio = await fetch('https://api-v2.dropcowboy.com/voice/public/tts/synthesize', {\n    method: 'POST',\n    headers: { 'x-key': process.env.DC_KEY, 'x-secret': process.env.DC_SECRET, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ text: 'Hi, this is Alex from Acme. Leave a message.', voice_id: 'e2b7c9d4-3f1a-4c8e-9b6d-7a5f0e1c2d3b' })\n  }).then(function (r) { return r.json(); });\n  const twiml = new VoiceResponse();\n  twiml.play(audio.data.audio_url);\n  res.type('text/xml').send(twiml.toString());\n});","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"voice\"],\"ttl_seconds\":900}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/tts","api_doc_url":"https://www.dropcowboy.com/developers/api/voice#text-to-speech","doc_path":"v2/docs/embed/building-blocks/tts.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/tts/SKILL.md"},{"id":"voice-clone","name":"Voice Clone (Mimic AI)","category":"voice","kind":"api","status":"available","package":"REST","summary":"Clone a voice from a recording you have permission to use.","apiDocUrl":"https://www.dropcowboy.com/developers/api/voice#clone-a-voice","deliveryModes":["Server request","Browser request with a site token"],"transports":["REST","TwiML"],"auth":"API key and secret on your server (media:write). From a browser, send Authorization: Bearer with a site token minted with the media scope.","snippets":{"curl":"curl -X POST https://api-v2.dropcowboy.com/voice/public/voices/clone \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"media_id\":\"5a4b3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d\",\"name\":\"Sales voice\"}'","twiml":"app.post('/twilio/recording-complete', async function (req, res) {\n  const media = await fetch('https://api-v2.dropcowboy.com/media/public/media', {\n    method: 'POST',\n    headers: { 'x-key': process.env.DC_KEY, 'x-secret': process.env.DC_SECRET, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ url: req.body.RecordingUrl + '.wav', name: 'Twilio call ' + req.body.CallSid })\n  }).then(function (r) { return r.json(); });\n  const job = await fetch('https://api-v2.dropcowboy.com/voice/public/voices/clone', {\n    method: 'POST',\n    headers: { 'x-key': process.env.DC_KEY, 'x-secret': process.env.DC_SECRET, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ media_id: media.data.media_id, name: 'Cloned from ' + req.body.CallSid })\n  }).then(function (r) { return r.json(); });\n  res.sendStatus(200);\n});","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"media\"],\"ttl_seconds\":900}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/voice-clone","api_doc_url":"https://www.dropcowboy.com/developers/api/voice#clone-a-voice","doc_path":"v2/docs/embed/building-blocks/voice-clone.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/voice-clone/SKILL.md"},{"id":"asr","name":"Speech-to-Text (ASR)","category":"voice","kind":"api","status":"available","package":"REST","summary":"Turn a recording into a transcript.","apiDocUrl":"https://www.dropcowboy.com/developers/api/voice#transcription","deliveryModes":["Server request","Browser request with a site token"],"transports":["REST","TwiML"],"auth":"API key and secret on your server (media:read). From a browser, send Authorization: Bearer with a site token minted with the media scope.","snippets":{"curl":"curl -X POST https://api-v2.dropcowboy.com/voice/public/asr/transcribe \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"media_id\":\"5a4b3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d\"}'","twiml":"app.post('/twilio/recording-complete', async function (req, res) {\n  const media = await fetch('https://api-v2.dropcowboy.com/media/public/media', {\n    method: 'POST',\n    headers: { 'x-key': process.env.DC_KEY, 'x-secret': process.env.DC_SECRET, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ url: req.body.RecordingUrl + '.wav', name: 'Twilio call ' + req.body.CallSid })\n  }).then(function (r) { return r.json(); });\n  const transcript = await fetch('https://api-v2.dropcowboy.com/voice/public/asr/transcribe', {\n    method: 'POST',\n    headers: { 'x-key': process.env.DC_KEY, 'x-secret': process.env.DC_SECRET, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ media_id: media.data.media_id })\n  }).then(function (r) { return r.json(); });\n  saveTranscriptToCrm(req.body.CallSid, transcript.data.text);\n  res.sendStatus(200);\n});","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"media\"],\"ttl_seconds\":900}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/asr","api_doc_url":"https://www.dropcowboy.com/developers/api/voice#transcription","doc_path":"v2/docs/embed/building-blocks/asr.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/asr/SKILL.md"},{"id":"recording-studio","name":"Recording Studio","category":"voice","kind":"widget","status":"available","package":"JavaScript","summary":"Record, upload, or generate a greeting.","deliveryModes":["JavaScript","Server request"],"transports":["JavaScript","Server request"],"auth":"Site token with the media scope. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.studio.init({ token: SITE_TOKEN });\nDropCowboy.studio.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nDropCowboy.studio.open();\nconst stop = DropCowboy.studio.addErrorListener(function (event) {});\nDropCowboy.studio.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"media\"],\"ttl_seconds\":900}'","curl":"curl -X POST https://api-v2.dropcowboy.com/media/public/media \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://files.example.com/greeting.mp3\",\"ext\":\".mp3\",\"name\":\"Greeting\"}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/recording-studio","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/recording-studio.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/recording-studio/SKILL.md"},{"id":"webforms","name":"Web Forms","category":"capture","kind":"loader","status":"available","package":"webforms.dropcowboy.com shim (live)","summary":"Lead-capture forms with TCPA consent built in.","deliveryModes":["Loader script (live)"],"transports":["Loader script"],"auth":"Per-webform ID (public embed)","snippets":{"script":"<div class=\"dropcowboy-form\"></div>\n<script src=\"https://webforms.dropcowboy.com/f/YOUR_WEBFORM_ID.js\" defer></script>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/webforms","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/webforms.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/webforms/SKILL.md"},{"id":"consent","name":"Consent Capture","category":"capture","kind":"widget","status":"available","package":"JavaScript","summary":"Capture a yes before you call or text, tied to the number.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.consent.init({ token: SITE_TOKEN });\nDropCowboy.consent.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nconst record = await DropCowboy.consent.captureConsent('+15125550148', { text: 'I agree to receive calls and texts.' });\nDropCowboy.consent.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'","html":"<dc-consent text=\"I agree to receive calls and texts.\"></dc-consent>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/consent","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/consent.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/consent/SKILL.md"},{"id":"click-to-call","name":"Click-to-Call","category":"capture","kind":"widget","status":"available","package":"JavaScript","summary":"A button that calls you, or requests a callback.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.clickToCall.init({ token: SITE_TOKEN });\nDropCowboy.clickToCall.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nawait DropCowboy.clickToCall.startCall('+15125550100');\nDropCowboy.clickToCall.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'","html":"<dc-click-to-call number=\"+15125550100\"></dc-click-to-call>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/click-to-call","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/click-to-call.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/click-to-call/SKILL.md"},{"id":"click-to-text","name":"Click-to-Text","category":"capture","kind":"widget","status":"available","package":"JavaScript","summary":"A button that starts an SMS to your business number.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.clickToText.init({ token: SITE_TOKEN });\nDropCowboy.clickToText.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nawait DropCowboy.clickToText.sendMessage('+15125550100', { body: 'Hi' });\nDropCowboy.clickToText.close();","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"dialer:webrtc\"],\"ttl_seconds\":900}'","html":"<dc-click-to-text number=\"+15125550100\" prefill=\"Hi\"></dc-click-to-text>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/click-to-text","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/click-to-text.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/click-to-text/SKILL.md"},{"id":"contact-pipeline","name":"Contacts & Pipeline","category":"contacts","kind":"widget","status":"available","package":"JavaScript","summary":"Open a contact card, timeline, and pipeline stage.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token with the contacts scope. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.contacts.init({ token: SITE_TOKEN });\nDropCowboy.contacts.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nDropCowboy.contacts.openContact('6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f');","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"contacts\"],\"ttl_seconds\":900}'","html":"<dc-contact-card contact-id=\"6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f\"></dc-contact-card>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/contact-pipeline","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/contact-pipeline.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/contact-pipeline/SKILL.md"},{"id":"campaigns","name":"Campaign Builders","category":"campaigns","kind":"widget","status":"available","package":"JavaScript","summary":"Show campaign status and progress inside your app.","deliveryModes":["JavaScript","HTML tag"],"transports":["JavaScript","HTML tag"],"auth":"Site token with the campaigns scope. Your API secret stays on your server.","snippets":{"script":"await DropCowboy.campaigns.init({ token: SITE_TOKEN });\nDropCowboy.campaigns.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });\nconst status = await DropCowboy.campaigns.getStatus('3f8a2c14-9b07-4e63-8d51-a6c0e2f49b1d');","http":"# On your server: trade your API key (needs numbers:write) for a site token. 1 hour max.\n# site_id is one UUID per app; generate your own in place of the example.\ncurl -s -X POST https://api-v2.dropcowboy.com/phone/public/embed/token \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"site_id\":\"00000000-0000-4000-8000-000000000000\",\"scope\":[\"campaigns\"],\"ttl_seconds\":900}'","html":"<dc-campaign-status campaign-id=\"3f8a2c14-9b07-4e63-8d51-a6c0e2f49b1d\"></dc-campaign-status>","curl":"curl -X POST https://api-v2.dropcowboy.com/campaign/public/campaigns \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"type\":\"ai_broadcast\",\"campaign_data\":{\"name\":\"Spring follow-up\",\"list_ids\":[\"8f3e1a9c-2d4b-4e7a-9c1f-5b6a7c8d9e0f\"],\"phone_line_id\":\"e2b6f9a3-5c1d-4e8b-a4f7-9c3e1b5d7a28\",\"brand_id\":\"2c9d4e1f-7a3b-4f6c-8d2e-9b1a5c7e3f40\",\"ai_agent\":{\"agent_id\":\"a9c3e8f1-4b2d-4a7c-8e9b-1c2d3e4f5a6b\"}}}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/campaigns","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/campaigns.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/campaigns/SKILL.md"},{"id":"analytics","name":"Website Analytics & Events","category":"developer","kind":"loader","status":"available","package":"dropcowboy-loader (live)","summary":"Page views, sessions, and custom events from your site.","deliveryModes":["Loader script (headless, live)"],"transports":["Loader script"],"auth":"Site-scoped (Origin enforced)","snippets":{"script":"<script src=\"https://webforms.dropcowboy.com/latest/dropcowboy-loader.min.js\"\n        data-site-id=\"YOUR_SITE_ID\"\n        defer></script>\n<script>document.addEventListener('DOMContentLoaded', function () { DropCowboy.track('signup_started', { plan: 'pro' }); });</script>"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/analytics","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/analytics.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/analytics/SKILL.md"},{"id":"headless-mcp","name":"Headless API & MCP","category":"developer","kind":"api","status":"available","package":"REST + MCP (live)","summary":"REST and MCP for servers and LLM agents. No widget.","deliveryModes":["Headless REST","MCP"],"transports":["REST","MCP"],"auth":"API key and secret on your server. Looking up blocks at /mcp/public or /building-blocks needs no key.","snippets":{"curl":"curl -X POST https://api-v2.dropcowboy.com/sms \\\n  -H \"x-key: $KEY\" -H \"x-secret: $SECRET\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"to\":\"+15125550148\",\"phone_line_id\":\"e2b6f9a3-5c1d-4e8b-a4f7-9c3e1b5d7a28\",\"body\":\"Hi from Drop Cowboy\"}'"},"status_label":"Available","is_available":true,"doc_url":"https://www.dropcowboy.com/developers/building-blocks/headless-mcp","api_doc_url":null,"doc_path":"v2/docs/embed/building-blocks/headless-mcp.md","skill_path":"https://github.com/Drop-Cowboy/dropcowboy/blob/main/skills/headless-mcp/SKILL.md"}]}