Media

The media library holds your audio files, MP3 or WAV. Add a file here once, then send it by its media_id as many times as you like. Add a file from a public URL in one call, or upload the bytes yourself with a signed upload.

Where you use media

Where Field
Ringless voicemail (POST /rvm) media_id
Voice broadcasts (POST /voice-broadcast) media_on_speech, media_on_beep, media_on_transfer, media_on_confirm, media_on_opt_out
Audio MMS (POST /sms, POST /phone/public/sms/reply) media_ids. See MMS.
Transcription and voice cloning media_id, plus ext

The library stores audio only. To send an image, pass media_urls on the text instead.

For an audio MMS, the stored file must be 1 MiB or smaller. A voicemail recording is often larger, so export a shorter or lower-bitrate MP3 for MMS.

When you pass a media_id to transcription or voice cloning, also pass the extension you stored, for example "ext": ".mp3". Without it, .wav is assumed. See Audio formats.

Routes

Method Route Scope What it does
GET /media/public/media media:read List your playable media
POST /media/public/media media:write Add media from a URL, or start a signed upload
POST /media/public/media/{media_id}/complete media:write Finish a signed upload
GET /media/public/media/{media_id}/policy media:write Get fresh upload URLs
GET /media/public/media/{media_id} media:read Get one media entry
PUT /media/public/media/{media_id} media:write Rename or relabel media
DELETE /media/public/media/{media_id} media:write Delete media

List media

Returns the media you can send, newest first. An entry waiting for its signed upload to finish isn't listed.

Field Type Required Description
skip integer No Entries to skip. Default 0.
limit integer No Page size. Default 100.
curl "https://api-v2.dropcowboy.com/media/public/media?limit=10" \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
  "data": {
    "medias": [
      {
        "team_id": "cd5cd773-4617-4b28-854d-d3adc74c96d5",
        "media_id": "0786a81e-e11e-4e53-ab64-71f552db23b3",
        "name": "September promo",
        "created_at": 1757491200000,
        "approved_at": 1757491200000,
        "api_allowed": true
      }
    ],
    "total": 1
  },
  "meta": { "request_id": "88f84098-c512-4585-9fd7-0d8bc8400944" }
}

data.total counts every playable entry, not just this page. Page with skip until you've read total entries. Timestamps are epoch milliseconds.

Create media

Send JSON with either url or signed_upload: true. The response is 201.

Field Type Required Description
name string Yes Display name.
type string No Your own label, for example rvm.
url string One of url or signed_upload Public URL of an MP3 or WAV file.
ext string No With url: the file's format, .wav (default) or .mp3.
signed_upload boolean One of url or signed_upload true to get signed URLs and upload the bytes yourself.

From a URL

We download the file while you wait. It must be 50 MiB or smaller and download within 15 seconds. When the call returns, the media is ready to send.

curl -X POST https://api-v2.dropcowboy.com/media/public/media \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "October follow-up",
    "type": "rvm",
    "url": "https://files.example.com/october-follow-up.mp3",
    "ext": ".mp3"
  }'
{
  "data": {
    "media_id": "55b9e55e-23f1-4c16-8865-f4b6261ebeea",
    "name": "October follow-up",
    "type": "rvm",
    "media_exists": true,
    "approved_at": 1759312800000,
    "api_allowed": true
  },
  "meta": { "request_id": "3028a01c-9f13-4158-a864-2daa70189301" }
}

If the download fails, no media is saved. Fix the URL and call again.

Signed upload

Use this when the file is on your own server rather than at a public URL.

  1. Create the entry with signed_upload: true. The response has upload.mp3 and upload.wav, each with a signed url and the content_type to send.
  2. PUT the file to the URL for its format, with exactly that Content-Type. The URLs are valid for 2 days.
  3. Call Complete a signed upload. Until you do, the entry has media_exists: false and can't be sent.
curl -X POST https://api-v2.dropcowboy.com/media/public/media \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "name": "October follow-up", "type": "rvm", "signed_upload": true }'
{
  "data": {
    "media_id": "55b9e55e-23f1-4c16-8865-f4b6261ebeea",
    "name": "October follow-up",
    "type": "rvm",
    "signed_upload": true,
    "media_exists": false,
    "api_allowed": false,
    "upload": {
      "mp3": { "url": "https://uploads.example.com/55b9e55e-23f1-4c16-8865-f4b6261ebeea.mp3?X-Amz-Signature=...", "content_type": "audio/mpeg" },
      "wav": { "url": "https://uploads.example.com/55b9e55e-23f1-4c16-8865-f4b6261ebeea.wav?X-Amz-Signature=...", "content_type": "audio/wav" }
    }
  },
  "meta": { "request_id": "50bb4bbb-3f86-459a-9761-f8bd7ff12f1b" }
}
curl -X PUT "$UPLOAD_MP3_URL" \
  -H "Content-Type: audio/mpeg" \
  --data-binary @october-follow-up.mp3

Complete a signed upload

Call this after your PUT succeeds. The media is then ready to send.

curl -X POST https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea/complete \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
  "data": {
    "media_id": "55b9e55e-23f1-4c16-8865-f4b6261ebeea",
    "media_exists": true,
    "approved_at": 1759313100000,
    "api_allowed": true
  },
  "meta": { "request_id": "764ff1bd-86e1-49af-8703-2ad22b53f04a" }
}

Refresh upload URLs

Returns new signed upload URLs for an entry, in the same mp3 and wav shape as upload. Call it when a PUT is rejected because the URL expired.

curl https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea/policy \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
  "data": {
    "mp3": { "url": "https://uploads.example.com/55b9e55e-23f1-4c16-8865-f4b6261ebeea.mp3?X-Amz-Signature=...", "content_type": "audio/mpeg" },
    "wav": { "url": "https://uploads.example.com/55b9e55e-23f1-4c16-8865-f4b6261ebeea.wav?X-Amz-Signature=...", "content_type": "audio/wav" }
  },
  "meta": { "request_id": "e2db9755-0c26-4aae-823a-dfb1b7c05acf" }
}

Get media

curl https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
  "data": {
    "_id": "66f2b1c4e8a9d3f1a2b4c6d8",
    "team_id": "cd5cd773-4617-4b28-854d-d3adc74c96d5",
    "media_id": "55b9e55e-23f1-4c16-8865-f4b6261ebeea",
    "media_exists": true,
    "name": "October follow-up",
    "type": "rvm",
    "src_url": "https://files.example.com/october-follow-up.mp3",
    "created_at": 1759312800000,
    "created_by": "fa933d82-485f-43b0-80ab-860121f06980",
    "modified_at": null,
    "modified_by": null,
    "deleted_at": null,
    "deleted_by": null,
    "approved_at": 1759312800000
  },
  "meta": { "request_id": "787d0f0b-aa13-4ce9-890c-202d68b72467" }
}

A deleted entry returns 404, so a media_id you stored earlier is safe to send only if this call still finds it.

Update media

Changes the name or type. The audio can't be replaced: create new media instead.

Field Type Required Description
name string No New display name.
type string No New label.
curl -X PUT https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "name": "October follow-up v2" }'
{
  "data": {
    "team_id": "cd5cd773-4617-4b28-854d-d3adc74c96d5",
    "media_id": "55b9e55e-23f1-4c16-8865-f4b6261ebeea",
    "modified_at": 1759399200000,
    "modified_by": "fa933d82-485f-43b0-80ab-860121f06980",
    "name": "October follow-up v2"
  },
  "meta": { "request_id": "c6e0e173-ab7e-45d6-b470-72d593b15f56" }
}

The response echoes the change even when the media_id doesn't exist. To confirm an entry exists, get it first.

Delete media

Removes the entry from your library. Messages already sent aren't affected.

curl -X DELETE https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
{
  "data": { "deleted": true },
  "meta": { "request_id": "964c9795-8bdd-475a-917a-2ec2727c2cfb" }
}

Errors

Status When What to do
400 The url isn't a public http or https address. Host the file somewhere reachable from the internet.
413 The file at url is larger than 50 MiB. Export a smaller file.
502 The server at url returned an error or closed the connection. Open the URL yourself to check it, then call again.
504 The file didn't download within 15 seconds. Use faster hosting, or a signed upload.
400 On complete: Upload not found. PUT audio to the signed URL first. Upload the file to a signed URL, then complete. If the URL expired, refresh it.
404 The media_id isn't on your account, or was deleted. Check the id with List media.

Sends that use media report their own outcomes. 3033 (Media Not Found) means the media_id was deleted, belongs to another account, or its upload was never completed. 3035 (Media Too Large) means the file is over the MMS size limit. See Outcomes for both. For every other error, see Responses, errors and limits.

Code samples

The requests from this page, ready to copy. Set DC_KEY and DC_SECRET to your API key pair first.

List media
curl "https://api-v2.dropcowboy.com/media/public/media?limit=10" \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
From a URL
curl -X POST https://api-v2.dropcowboy.com/media/public/media \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "October follow-up",
    "type": "rvm",
    "url": "https://files.example.com/october-follow-up.mp3",
    "ext": ".mp3"
  }'
Signed upload
curl -X POST https://api-v2.dropcowboy.com/media/public/media \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "name": "October follow-up", "type": "rvm", "signed_upload": true }'
Signed upload (2)
curl -X PUT "$UPLOAD_MP3_URL" \
  -H "Content-Type: audio/mpeg" \
  --data-binary @october-follow-up.mp3
Complete a signed upload
curl -X POST https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea/complete \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
Refresh upload URLs
curl https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea/policy \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
Get media
curl https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET"
Update media
curl -X PUT https://api-v2.dropcowboy.com/media/public/media/55b9e55e-23f1-4c16-8865-f4b6261ebeea \
  -H "x-key: $DC_KEY" -H "x-secret: $DC_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "name": "October follow-up v2" }'