Upload Attachment
Messages
Upload Attachment
Upload an audio clip, image, video, or PDF and get a public, workspace-owned URL to use as an attachmentUrl. REST endpoint in the Tuco AI iMessage API — bearer-token auth, multipart upload.
POST
Upload Attachment
Use this endpoint to turn a local file into a public, workspace-owned URL you can
drop straight into
attachmentUrls on
POST /api/messages or into the GHL Send voice note action. The URL is signed for
your workspace, so it always passes the “does not belong to this organization” guard —
no need to host the file yourself.Authentication
Pass your workspace API key as a Bearer token (the same key as/api/messages), or
use a Clerk session token.
Request
Send amultipart/form-data request with a single file field. There is no JSON
body — this is a file upload.
file
required
The file to upload, as a multipart
file field. Max 25 MB. Type is validated by
file extension (browsers report unreliable MIME for .caf/.heic).Allowed types
Voice notes: upload any of the audio formats above. When the file is used with
voiceNote: true (GHL action) or otherwise flagged for a voice note, the worker
transcodes it to the native iMessage voice-note bubble — you do not have to convert
to .caf yourself first.Example
Response
Returns200 OK with the public URL and file metadata.
string
A public, signed link hosted on your workspace storage. Use it directly as an
attachmentUrl — it needs no auth to fetch and always passes the /api/messages
org-ownership guard. Valid for ~1 year; re-upload if a workflow may run longer.string
The original filename you uploaded.
number
File size in bytes.
string | null
The uploaded file’s MIME type, or
null when the browser/client didn’t report one
(common for .caf/.heic). Delivery does not depend on this field.string
The Clerk organization ID that owns the file — the workspace your API key belongs to.
Using the URL
1
Upload the file
POST /api/attachments/upload with your audio/image/etc. as the file field.
Grab url from the response.2
Send it
Pass
url as an attachmentUrl — in attachmentUrls on
POST /api/messages, or in the GHL
Send voice note action.3
Re-upload if it's older than a year
The signed link is valid for ~1 year. For a long-running workflow, re-upload
periodically so the URL never expires mid-campaign.
No-code alternative: the Uploads UI
You don’t need to call the API to get a URL. In the dashboard:/uploads— a dedicated Upload audio etc page.- The Upload audio etc tab on the Leads page.