API reference / Account and reference
Account
These routes read your account details, your balance and your users. They also set up Building Blocks: check what's missing, switch it on, and connect your own carrier (BYOC). API keys are on Authentication.
Routes
| Method | Route | Scope | What it does |
|---|---|---|---|
GET |
/register/public/account |
balance:read |
Get account info |
GET |
/campaign/public/balance |
balance:read |
Get your balance |
GET |
/user/public/users |
contacts:read |
List users |
GET |
/register/public/integration-readiness |
balance:read |
Check Building Blocks readiness |
POST |
/register/public/building-blocks/enable |
account:write |
Enable Building Blocks |
POST |
/register/public/building-blocks/contact-consent |
account:write |
Use existing contact consent in widgets |
GET |
/integration/public/byoc |
balance:read |
Get carrier status |
POST |
/integration/public/byoc/connect |
account:write |
Connect a carrier |
POST |
/integration/public/byoc/disconnect |
account:write |
Disconnect a carrier |
Get account info
GET /register/public/account returns your account id, its owner and your
contact frequency limit.
curl https://api-v2.dropcowboy.com/register/public/account \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"team_id": "4e9a2c7f-1b5d-4f3e-8c6a-9d2b7e4f1a53",
"owner": {
"user_id": "auth0|65f1c2d3e4a5b6c7d8e9f0a1",
"first_name": "Jordan",
"last_name": "Rivera",
"email": "jordan@example.com"
},
"delivery_limits": {
"frequency": {
"max_attempts": 3,
"window_days": 3,
"window_ms": 259200000,
"source": "default"
}
}
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
| Field | Type | Description |
|---|---|---|
team_id |
string | Your account id. |
owner |
object | The account owner, or null if there is none. |
owner.user_id |
string | The owner's user id. It's an opaque string, not a UUID. |
owner.first_name, owner.last_name, owner.email |
string | The owner's name and email. |
delivery_limits.frequency.max_attempts |
integer | Most attempts to one phone number within the window. |
delivery_limits.frequency.window_days |
number | The window, in days. |
delivery_limits.frequency.window_ms |
integer | The window, in milliseconds. |
delivery_limits.frequency.source |
string | team if your account sets its own limit, default if it uses the platform default. |
You change the limit in the dashboard, not the API. See Contact frequency limit.
Get your balance
GET /campaign/public/balance returns your prepaid balance in US dollars.
One balance pays for every channel.
curl https://api-v2.dropcowboy.com/campaign/public/balance \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"balance": 250.75,
"reserved": 12.5,
"available": 238.25,
"recharge_amount": 100,
"recharge_threshold": 25,
"nag_no_funds_at": null
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
| Field | Type | Description |
|---|---|---|
balance |
number | Your current balance. |
reserved |
number | Held for sends that haven't settled yet. |
available |
number | What you can spend: balance minus reserved. |
recharge_amount |
number | What's charged automatically when the balance falls below recharge_threshold. |
recharge_threshold |
number | The balance that triggers an automatic recharge. |
nag_no_funds_at |
integer | When you were last told you were out of funds, in epoch milliseconds. null if never. |
An account that has never been funded gets an empty object in data.
Sends don't fail with 402 when the balance runs out. They fail later with
outcome 3000 (No Funds). See Balance.
List users
GET /user/public/users lists the users on your account.
curl "https://api-v2.dropcowboy.com/user/public/users?limit=50&skip=0" \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
integer | No | Users per page, up to 100. Defaults to 50. |
skip |
integer | No | Users to skip, for paging. Defaults to 0. |
search_term |
string | No | Only users whose first name, last name or email starts with this. |
{
"data": {
"users": [
{
"_id": "7c2e9a4f-6b1d-4e8a-9f3c-2d5b8e1a7c46",
"user_id": "auth0|65f1c2d3e4a5b6c7d8e9f0a1",
"username": "jordan@example.com",
"team_id": "4e9a2c7f-1b5d-4f3e-8c6a-9d2b7e4f1a53",
"role_id": "3f7a1c9e-5d2b-4e8f-a6c3-9b1d7e4f2a85",
"status": "ENABLED",
"owner": true,
"identity": {
"first_name": "Jordan",
"last_name": "Rivera",
"email": "jordan@example.com"
},
"created_at": 1774041600000
}
],
"total_users": 1
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
| Field | Type | Description |
|---|---|---|
user_id |
string | The user's id. Pass this wherever another route asks for a user or owner. It's an opaque string, not a UUID. |
username |
string | The user's sign-in name. |
role_id |
string | The id of the user's role. |
status |
string | ENABLED or DISABLED. A disabled user can't sign in. |
owner |
boolean | true for the account owner. |
identity |
object | first_name, last_name and email. |
created_at |
integer | When the user was added, in epoch milliseconds. |
total_users |
integer | Users matching the request, across all pages. |
A field the user doesn't have comes back as null.
Check Building Blocks readiness
GET /register/public/integration-readiness tells you what's still missing
before Building Blocks widgets can place calls on your carrier.
curl https://api-v2.dropcowboy.com/register/public/integration-readiness \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"force_byoc": true,
"building_blocks_enabled": true,
"embed_resolve_contact_consent": false,
"usage_plan": "usage-plan-builder",
"byoc": {
"connected": true,
"providers": [
{
"provider": "twilio",
"integration_type": "twilio",
"integration_id": "2f8c4a6e-9b3d-4e1f-a7c5-6d2b9e4f1a38",
"enabled": true,
"default": true,
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61"
}
],
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61"
},
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61",
"numbers": {
"count": 1,
"items": [
{ "number_id": "8a3d6f1c-4e9b-4c2a-b7e5-1f8d3a6c9e24", "phone_number": "+13125550100", "name": "Main line" }
]
},
"voices": { "count": 2 },
"agents": { "count": 1, "published": 0 },
"funds": { "available": 238.25, "balance": 250.75, "reserved": 12.5, "funds_ok": true },
"allotment": {
"sms": { "remaining": 412, "cap": 500 }
},
"embed_ready": true,
"next_actions": []
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
| Field | Type | Description |
|---|---|---|
embed_ready |
boolean | true when widgets can place calls: Building Blocks is on, a carrier is connected, and you have funds. |
next_actions |
array | What to do next, in order. Empty when embed_ready is true. |
force_byoc |
boolean | Calls and texts go through your own carrier. |
building_blocks_enabled |
boolean | Building Blocks is on. It is on for every team billed for its own carrier (BYOC), so it matches force_byoc. |
embed_resolve_contact_consent |
boolean | Widgets may use a contact's existing consent. See Use existing contact consent in widgets. |
usage_plan |
string | Your plan id. |
byoc |
object | Your carrier connections. Same shape as Get carrier status. |
pool_id |
string | Your carrier connection, or null. |
numbers |
object | count of your numbers and up to 50 of them in items. |
voices.count |
integer | Voices on your account. |
agents |
object | AI agents: count, and how many are published. |
funds |
object | balance, reserved, available, and funds_ok, which is true when you have balance or plan allowance left. |
allotment |
object | The included usage left on your plan, per product, as remaining and cap. Products are dialer_minutes, voice_ai_minutes, sms, rvm, detection_minutes, tts_characters, asr_minutes, mimic_voices and email. |
Each next_actions value names one step:
| Value | What to do |
|---|---|
enable_building_blocks |
Enable Building Blocks. |
connect_byoc |
Connect a carrier. |
add_funds |
Add funds in the dashboard. |
rent_number |
Rent a number. See Phone numbers. |
create_agent |
Create an AI agent. See AI agents. |
publish_agent |
Publish your AI agent. See AI agents. |
Enable Building Blocks
POST /register/public/building-blocks/enable switches Building Blocks on.
If you aren't already on a bring-your-own-carrier plan, it also moves you to
the developer plan and releases every phone number you rent from
Drop Cowboy®. Confirm this by sending confirm_leave_retail: true.
curl -X POST https://api-v2.dropcowboy.com/register/public/building-blocks/enable \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "confirm_leave_retail": true }'
| Field | Type | Required | Description |
|---|---|---|---|
confirm_leave_retail |
boolean | Yes | Must be true. |
{
"data": {
"success": true,
"building_blocks_enabled": true,
"plan_switched": true,
"plan_id": "usage-plan-builder",
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61"
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
| Field | Type | Description |
|---|---|---|
plan_switched |
boolean | true if your plan changed. false if you were already on a bring-your-own-carrier plan. |
plan_id |
string | Your plan after the call. |
pool_id |
string | Your carrier connection, or null if you haven't connected one. |
Use existing contact consent in widgets
POST /register/public/building-blocks/contact-consent turns on or off a
setting that lets widgets text or call back a contact who already gave consent
in Drop Cowboy. It's off by default. While it's off, every text or callback to
a US number from a widget needs a consent_id from Consent Capture.
curl -X POST https://api-v2.dropcowboy.com/register/public/building-blocks/contact-consent \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "enabled": true }'
| Field | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | Yes | true to turn the setting on, false to turn it off. |
{
"data": {
"success": true,
"embed_resolve_contact_consent": true
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
When the setting is on and a widget sends contact_id without consent_id,
Drop Cowboy uses that contact's consent only if all of these are true:
- The contact is in your account.
- The number being texted or called is one of the contact's numbers.
- The contact has granted consent for that channel: texting consent for a text, calling consent for a callback.
- The contact hasn't opted out or replied STOP since that consent, and isn't on your Do Not Call list.
Otherwise the send fails with 403 and consent_required, the same as when
the setting is off. A contact imported with only a consent flag and no
recorded consent doesn't qualify. If a dashboard user calls this route, they
need permission to edit the Trust Center.
Get carrier status
GET /integration/public/byoc lists the carriers you've connected.
curl https://api-v2.dropcowboy.com/integration/public/byoc \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
"data": {
"connected": true,
"providers": [
{
"provider": "twilio",
"integration_type": "twilio",
"integration_id": "2f8c4a6e-9b3d-4e1f-a7c5-6d2b9e4f1a38",
"enabled": true,
"default": true,
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61"
}
],
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61"
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
| Field | Type | Description |
|---|---|---|
connected |
boolean | true if at least one carrier is connected. |
providers |
array | One entry per connected carrier: its name in provider, whether it's enabled and the default, and its pool_id. |
pool_id |
string | Your carrier connection, or null. |
Connect a carrier
POST /integration/public/byoc/connect connects your account at a carrier
so calls and texts go through it.
curl -X POST https://api-v2.dropcowboy.com/integration/public/byoc/connect \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{
"provider": "twilio",
"credentials": {
"account_sid": "<your Twilio account SID>",
"auth_token": "<your Twilio auth token>"
},
"enabled": true,
"default": true
}'
| Field | Type | Required | Description |
|---|---|---|---|
provider |
string | Yes | twilio, thinq, telnyx, signalwire, plivo, bandwidth, vonage, sinch, flowroute or custom. |
credentials |
object | Yes | Your API credentials at the carrier. Use the keys that match what the carrier issues: account_sid and auth_token, account_id and account_token, username and password, or api_token. |
enabled |
boolean | No | Send true to use this carrier. Defaults to false. |
default |
boolean | No | Send true to make this your default carrier. Defaults to false. |
channels |
integer | No | The most simultaneous calls to send to this carrier. |
cps |
integer | No | The most calls to start per second on this carrier. |
{
"data": {
"connected": true,
"provider": "twilio",
"integration_type": "twilio",
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61",
"public_data": {
"enabled": true,
"default": true,
"pool_id": "6e1f3a5c-9b2d-4c8e-a7f1-3d5b9c2e4a61"
}
},
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
Connecting the same carrier again updates its settings.
Disconnect a carrier
POST /integration/public/byoc/disconnect removes a carrier connection.
curl -X POST https://api-v2.dropcowboy.com/integration/public/byoc/disconnect \
-H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
-H "Content-Type: application/json" \
-d '{ "provider": "twilio" }'
| Field | Type | Required | Description |
|---|---|---|---|
provider |
string | Yes | The carrier to disconnect. |
{
"data": { "disconnected": true, "provider": "twilio", "integration_type": "twilio" },
"meta": { "request_id": "c2a6e8f4-3b9d-4c1e-8a7f-5d3b1e9c6a24" }
}
Errors
| Status | When | What to do |
|---|---|---|
400 |
confirm_leave_retail isn't true, or provider isn't one of the listed carriers |
Fix the field named in detail |
403 |
The credential lacks the route's scope | Use a credential with that scope |
404 |
The account wasn't found | Check the credential belongs to the right account |
Errors use the format in Responses, errors and limits.
BYOC customers connect their own carrier accounts (Twilio, Bandwidth, etc.) to the Drop Cowboy platform. Customers are responsible for their carrier relationship, billing, and compliance with carrier terms of service. Drop Cowboy does not mark up or bill for carrier services. Message delivery and carrier connectivity depend on the customer's carrier account status and settings.