Building Blocks / Contacts & Pipeline
Contacts & Pipeline
Open a contact card, timeline, and pipeline stage.
Drop-in widget. Load
https://webforms.dropcowboy.com/latest/dropcowboy-contacts.min.jsand pass it a site token your server mints. Do not rebuild the contact timeline or the pipeline board; the widget already does it.
When to use this vs REST
Use Contacts and Pipeline to show a Drop Cowboy® contact card, timeline, and stage in your app. Use REST to sync contacts in bulk.
Do not rebuild
- The contact timeline (calls, texts, voicemails).
- Pipeline boards and drag and drop.
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: ['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.
# site_id is one UUID per app; generate your own in place of the example.
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":"00000000-0000-4000-8000-000000000000","scope":["contacts"],"ttl_seconds":900}'
- Load the script, init with the token, and call a method:
<script src="https://webforms.dropcowboy.com/latest/dropcowboy-contacts.min.js"></script>
<div id="contact-slot"></div>
<script>
(async function () {
const minted = await fetch('/dropcowboy/token', { method: 'POST' }).then(function (r) { return r.json(); });
await DropCowboy.contacts.init({ token: minted.token });
DropCowboy.contacts.setTheme({ theme: 'LIGHT', primaryColor: '#009efb' });
async function showContact(dcContactId) {
await DropCowboy.contacts.openContact(dcContactId);
}
document.getElementById('contacts').addEventListener('click', function (e) {
var row = e.target.closest('[data-dc-contact-id]');
if (row) showContact(row.getAttribute('data-dc-contact-id'));
});
})();
</script>
Pin a version with SRI
/latest/ changes whenever we ship. To pin a release, load the same file from /vX.Y.Z/ and add its Subresource Integrity hash. Each release lists its hashes at https://webforms.dropcowboy.com/vX.Y.Z/building-blocks-manifest.json: take the integrity of the entry whose file is dropcowboy-contacts.js. It covers dropcowboy-contacts.min.js as well, because both names serve the same bytes.
<script src="https://webforms.dropcowboy.com/vX.Y.Z/dropcowboy-contacts.min.js"
integrity="sha384-INTEGRITY_FROM_MANIFEST"
crossorigin="anonymous"></script>
Do not put integrity on a /latest/ URL. The file changes under it and the browser will refuse to run it.
JS API / HTML tag
| Method | What it does |
|---|---|
init({ token, getToken }) |
Site token with contacts scope. Optional getToken returns a fresh site token (or { token, expires_at }) from your server; it runs before the token expires and once after a 401. |
setToken(token) |
Swaps in a site token you minted yourself. The next request uses it. |
window event 'dc-session-expired' |
Fires when the token expired and could not be refreshed. Mint a new one and call setToken(). |
setTheme({ theme, primaryColor }) |
LIGHT/DARK plus accent. |
openContact(contactId) |
Loads the card and timeline for that contact. |
listContacts({ limit, offset, search_term, list_id }) -> { contacts, total_contacts } |
Pages through your contacts (GET /contact/public/contacts). Retries once after a 401 through the token manager. |
searchContacts({ phone, email, limit, offset }) -> { contacts } |
Finds contacts by phone or email (GET /contact/public/contacts/search). Needs one of the two; use it to map a CRM record to a Drop Cowboy contact id. |
openBoard(boardId) |
Opens a pipeline board. Cards open with a click, Enter, or Space and fire dc-open-contact { contact_id }. Dragging a card to another stage, or picking one from its Move to stage menu, saves the move; if it fails the card goes back and the board fires dc-error. |
createContact(input) |
Creates a contact from the host CRM payload. |
setDisposition(contactId, disposition) |
Writes a call/SMS disposition onto the contact. |
moveCard(contactId, fromListId, toListId) |
Moves the contact between pipeline lists (POST /contact/public/contacts/{id}/lists/move). Rejects with code move_skipped when the contact is on a different brand than the target list. |
<dc-contact-timeline contact-id="..."> |
Loads its own activity once it has a contact-id and a session (set token or tokenManager, or let the script hand it the session). Fires dc-error when the timeline cannot be loaded. |
<dc-contact-card contact-id="..." campaigns> |
The campaigns attribute shows an Add to campaign button that fires dc-add-campaign. Without it the button is hidden. |
HTML tag:
<dc-contact-card contact-id="6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f"></dc-contact-card>
Auth and scopes
Site token with the contacts scope. Your API secret stays on your server.
Site token scope: 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.
- Map each of your records to a Drop Cowboy contact id before you open it. listContacts() and searchContacts() find the id by page, phone, or email.
- Dragging a card moves the contact from one stage list to the other and saves it. A contact on a different brand than the target list is not moved; the card goes back and the board fires dc-error. Without the contacts scope the cards cannot be dragged.
- Every card also has a Move to stage menu, so keyboard and single-pointer users can move it without dragging. Focus stays on the card in its new stage. The menu appears only with the contacts scope, like dragging.
- The Add to campaign button on the contact card shows only when you set the campaigns attribute and handle dc-add-campaign.
Related REST
Routes are on https://api-v2.dropcowboy.com.
- GET /contact/public/contacts
- GET /contact/public/contacts/search
- POST /contact/public/contacts
- POST /contact/public/contacts/{id}/lists/move - move between stages
- POST /phone/public/embed/token - mint the site token
Full reference: Embed site tokens, Contacts API.