Skip to the page

API reference

Upload a file

Uploads a picture, video, audio file, PDF or contact card (.vcf) of up to 25 MB to send.

POST/v1/files

Uploads a picture, video, audio file, PDF or contact card (.vcf) of up to 25 MB to send. Send the answer’s id in files on a send. A file nobody sends is deleted after a day.

Needs a key with the messages:send scope. Keys and scopes

Send an Idempotency-Key so a retry never acts twice. Idempotency

Headers

  • Idempotency-Keystring

    Any string of up to 255 characters, new for each request. A retry with the same key gets the first answer back for 24 hours, with Idempotent-Replayed: true.

    Up to 255 characters.

Request body

Send it as multipart/form-data.

  • filefilerequired

    The file, up to 25 MB: a picture, video, audio, a PDF or a contact card (.vcf).

  • namestring

    A name to send it under, if not the file’s own.

    Up to 255 characters.

Example

POST/v1/filesUpload a file →
curl -X POST "https://usebluebot.com/api/v1/files" \
  -H "Authorization: Bearer $BLUEBOT_API_KEY" \
  -H "Idempotency-Key: 0f6d8c2e-5b1a-4c7e-9d3f-2a8b6e1c4d70" \
  -F "file=@house.jpg"

Response

201: The file.

  • idstringrequired

    A file_ id.

    Starts with file_.

  • object"file"required
  • namestring or nullrequired

    The file name, as it was uploaded or as Messages named it.

  • content_typestringrequired

    The media type.

  • sizeintegerrequired

    Bytes.

  • kindstringrequired

    What the file is, for showing it: an image, a video, audio, a voice memo, a PDF, a contact card or another file.

    One of image, video, audio, voice_memo, pdf, contact_card, file.

  • statusstringrequired

    ready when BlueBot has the bytes; waiting while the Mac uploads them (usually seconds); too_large for an attachment over 25 MB, which the Mac never uploads; deleted once 30 days have passed.

    One of ready, waiting, too_large, deleted.

  • urlstring or nullrequired

    Reads the file for an hour. Null unless status is ready.

  • url_expires_attimestamp or nullrequired

    When url stops working.

  • transcriptstring or nullrequired

    For a voice memo, the words the Mac transcribed on the device, when the owner turned transcription on.

  • transcript_languagestring or nullrequired

    The transcript’s language, such as en-US.

  • created_attimestamprequired

    When BlueBot first knew of the file.

Response201
{
  "id": "file_1Hq2LxW9cVbN3mKpRtYs0a",
  "object": "file",
  "name": "listing-412-oak.jpg",
  "content_type": "image/jpeg",
  "size": 482113,
  "kind": "image",
  "status": "ready",
  "url": "https://usebluebot.com/files/f/2Bf8QzD4kJmA6nXwEuTr1c?sig=…",
  "url_expires_at": "2026-11-13T20:41:00.000Z",
  "transcript": null,
  "transcript_language": null,
  "created_at": "2026-11-13T19:40:00.000Z"
}

Errors

Every refusal has the same envelope and a page of its own. These are the ones this operation can give.

CodeStatusWhat it means
unauthorized401The request carried no key, or a key BlueBot doesn’t know: mistyped, revoked, or a test key sent to the live API.
insufficient_scope403The key doesn’t carry the scope the endpoint needs. Each endpoint’s reference names its scope.
rate_limited429Too many requests. A key may make 120 requests a minute. The RateLimit header says how many are left, and Retry-After how long to wait.
internal500Something went wrong on BlueBot’s side. It was reported. Send the request again; with an Idempotency-Key that is always safe.
invalid_request400Something in the request doesn’t fit: a missing or malformed field, a bad id, or a combination the endpoint refuses. details names each field.
payload_too_large413The request is bigger than the endpoint takes.
unsupported_media_type415The body isn’t a type the endpoint reads: JSON for most, a multipart form for file uploads, and only the file types listed for files.
plan_lapsed402The account’s plan isn’t active, so BlueBot isn’t taking new texts. Texts already queued wait and go once the plan is active again.
idempotency_conflict409The Idempotency-Key was used in the last 24 hours with a different request. A key stands for one request.
conflict409The request doesn’t fit the thing’s current state, or another request with the same Idempotency-Key is still running.

Try it

Call this operation from the page with your own key. The key stays in this tab and is forgotten when you leave.