Building Blocks / Campaigns
Campaign Builders
Show campaign status and start or pause from your app.
Drop-in widget. Load
https://webforms.dropcowboy.com/latest/dropcowboy-campaigns.min.jsand pass it a site token your server mints. Do not rebuild campaign status and progress displays; the widget already does it.The widget starts, pauses, and shows campaigns. Create them from your server over REST: email, AI calls, and every other type. See From your server below.
When to use this vs REST
Use the widget to show campaign status and start or pause from your app. Use REST to create campaigns from code; POST /campaign/public/campaigns takes type rvm, sms, email, voice_broadcast, or ai_broadcast.
Do not rebuild
- Campaign status and progress displays.
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: ['campaigns'], 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":["campaigns"],"ttl_seconds":900}'
- Load the script, init with the token, and call a method:
<script src="https://webforms.dropcowboy.com/latest/dropcowboy-campaigns.min.js"></script>
<script>
(async function () {
const minted = await fetch('/dropcowboy/token', { method: 'POST' }).then(function (r) { return r.json(); });
await DropCowboy.campaigns.init({ token: minted.token });
const status = await DropCowboy.campaigns.getStatus('3f8a2c14-9b07-4e63-8d51-a6c0e2f49b1d');
document.getElementById('campaign-state').textContent = status.status;
document.getElementById('pause').addEventListener('click', function () {
DropCowboy.campaigns.pause('3f8a2c14-9b07-4e63-8d51-a6c0e2f49b1d');
});
})();
</script>
From your server
The widget cannot create campaigns. Create them from your server with an API key: campaigns:write to create, campaigns:send to start or pause. Every campaign needs list_ids; look them up with GET /contact/public/lists.
Create an email campaign:
curl -X POST https://api-v2.dropcowboy.com/campaign/public/campaigns \
-H "x-key: $KEY" -H "x-secret: $SECRET" \
-H "Content-Type: application/json" \
-d '{"type":"email","campaign_data":{"name":"Spring newsletter","list_ids":["8f3e1a9c-2d4b-4e7a-9c1f-5b6a7c8d9e0f"],"email_from_mailbox_id":"c5f1a8d3-6e2b-4c9f-b1a7-8d4e2c6f9b35","email_subject":"Spring hours","email_html":"<p>We are open Saturdays this spring.</p>"}}'
Create an AI call campaign:
curl -X POST https://api-v2.dropcowboy.com/campaign/public/campaigns \
-H "x-key: $KEY" -H "x-secret: $SECRET" \
-H "Content-Type: application/json" \
-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"}}}'
Start a campaign:
curl -X POST https://api-v2.dropcowboy.com/campaign/public/campaigns/3f8a2c14-9b07-4e63-8d51-a6c0e2f49b1d/start \
-H "x-key: $KEY" -H "x-secret: $SECRET"
JS API / HTML tag
| Method | What it does |
|---|---|
init({ token }) |
Site token with the campaigns scope. |
getStatus(campaignId) |
Returns mapped status for one campaign. |
list(query) |
Lists campaigns. Optional status, type, search_term, limit. |
getStats(campaignId, query) |
Returns rollup stats. |
start(campaignId) |
Starts a paused/draft campaign. Confirm spend in the host if you set DropCowboy.confirmSpend. |
pause(campaignId) |
Pauses a running campaign. |
HTML tag:
<dc-campaign-status campaign-id="3f8a2c14-9b07-4e63-8d51-a6c0e2f49b1d"></dc-campaign-status>
Auth and scopes
Site token with the campaigns scope. Your API secret stays on your server.
Site token scope: campaigns. 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.
- The widget cannot create campaigns. Create them over REST.
- Each new campaign is scored for compliance risk. Low-risk campaigns are approved automatically; others wait for review (approved is false) before they can send.
- Starting a campaign is not delivery. Each contact's result arrives on the channel's status webhook.
Related REST
Routes are on https://api-v2.dropcowboy.com.
- POST /campaign/public/campaigns - create (campaigns:write)
- POST /campaign/public/campaigns/{id}/start - start (campaigns:send)
- POST /campaign/public/campaigns/{id}/pause - pause (campaigns:send)
- GET /campaign/public/campaigns - list
Full reference: Embed site tokens, Campaigns API, Webhooks.