Attachments

Pre-upload a file

This endpoint is optional. You can send media by simply providing a URL in your message's media part — no pre-upload required. Use this endpoint only when you want to upload a file ahead of time for reuse or latency optimization.

Returns a presigned upload URL and a reusable attachment_id you can reference in future messages. Attachments stored on the ephemeral attachments tier (and their URLs) are removed within roughly 24–48 hours of upload, independently of any message retention window. Attachments on the persistent tier are kept until you DELETE them, regardless of message expiry.

Step 1: Request an upload URL

Call POST /v3/attachments with file metadata:

{
  "filename": "photo.jpg",
  "content_type": "image/jpeg",
  "size_bytes": 1024000
}

The response includes an upload_url (valid for 15 minutes) and a reusable attachment_id.

Step 2: Upload the file

Make a PUT request to the upload_url with the raw file bytes as the request body. You must include all headers from required_headers exactly as returned — the presigned URL is signed with these values and S3 will reject the upload if they don't match.

The request body is the binary file content — not JSON, not multipart form data. The file must equal size_bytes bytes (the value you declared in step 1).

curl -X PUT "<upload_url from step 1>" \
  -H "Content-Type: image/jpeg" \
  -H "Content-Length: 1024000" \
  --data-binary @photo.jpg

Step 3: Send a message with the attachment

Reference the attachment_id in a media part with POST /v3/chats. The ID stays valid for as many messages as you want — unless the attachment is stored on the ephemeral attachments tier, in which case it is removed within roughly 24–48 hours of upload.

{
  "from": "+15559876543",
  "to": ["+15551234567"],
  "message": {
    "parts": [
      { "type": "media", "attachment_id": "<attachment_id from step 1>" }
    ]
  }
}

When to use this instead of a URL in the media part

  • Sending the same file to multiple recipients (avoids re-downloading each time)
  • Large files where you want to separate upload from message send
  • Latency-sensitive sends where the file should already be stored

If you just need to send a file once, skip all of this and pass a url directly in the media part instead.

File Size Limit: 100MB

Unsupported Types: WebP, SVG, FLAC, OGG, and executable files are explicitly rejected.

post/v3/attachments

Request

  • Base URL: https://api.linqapp.com/api/partner
  • URL: https://api.linqapp.com/api/partner/v3/attachments
  • Auth: HTTP bearer

Request body

filenamestring required

Name of the file to upload

content_type'image/jpeg' | 'image/png' | 'image/gif' | 'image/heic' | 'image/heif' | 'image/tiff' | 'image/bmp' | 'image/svg+xml' | 'image/webp' | 'image/x-icon' | 'video/mp4' | 'video/quicktime' | 'video/mpeg' | 'video/mpeg2' | 'video/x-m4v' | 'video/x-msvideo' | 'video/3gpp' | 'audio/mpeg' | 'audio/mp3' | 'audio/x-m4a' | 'audio/mp4' | 'audio/x-caf' | 'audio/x-wav' | 'audio/x-aiff' | 'audio/aiff' | 'audio/aac' | 'audio/midi' | 'audio/amr' | 'application/pdf' | 'application/vnd.apple.pkpass' | 'text/plain' | 'text/markdown' | 'text/vcard' | 'text/rtf' | 'text/csv' | 'text/html' | 'text/calendar' | 'application/msword' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | 'application/vnd.ms-excel' | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' | 'application/vnd.ms-powerpoint' | 'application/vnd.openxmlformats-officedocument.presentationml.presentation' | 'application/x-iwork-pages-sffpages' | 'application/x-iwork-numbers-sffnumbers' | 'application/x-iwork-keynote-sffkey' | 'application/epub+zip' | 'text/xml' | 'application/json' | 'application/zip' | 'application/x-gzip' required

Supported MIME types for file attachments and media URLs.

Images: image/jpeg, image/png, image/gif, image/heic, image/heif, image/tiff, image/bmp, image/svg+xml, image/webp, image/x-icon

Videos: video/mp4, video/quicktime, video/mpeg, video/mpeg2, video/x-msvideo, video/3gpp

Audio: audio/mpeg, audio/x-m4a, audio/x-caf, audio/x-wav, audio/x-aiff, audio/aac, audio/midi, audio/amr

Wallet passes: application/vnd.apple.pkpass

Documents: application/pdf, text/plain, text/markdown, text/vcard, text/rtf, text/csv, text/html, text/calendar, text/xml, application/json, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/x-iwork-pages-sffpages, application/x-iwork-numbers-sffnumbers, application/x-iwork-keynote-sffkey, application/epub+zip, application/zip, application/x-gzip

Transcoded on delivery:

  • audio/x-caf — CAF files are transcoded to audio/mp4 for delivery.

Deprecated (accepted but transcoded):

  • audio/mp3 — Deprecated. Use audio/mpeg instead. Files sent as audio/mp3 will be delivered as audio/mpeg.
  • audio/mp4 — Deprecated. Use audio/x-m4a instead. Files sent as audio/mp4 will be delivered as audio/x-m4a.
  • audio/aiff — Deprecated. Use audio/x-aiff instead. Files sent as audio/aiff will be delivered as audio/x-aiff.
  • image/tiff — Accepted, but TIFF images are transcoded to JPEG for delivery.

Unsupported: FLAC, OGG, and executable files are explicitly rejected.

size_bytesinteger required

Size of the file in bytes (max 100MB)

Example request

{
  "filename": "photo.jpg",
  "content_type": "image/jpeg",
  "size_bytes": 1024000
}

Response

Upload URL generated successfully

attachment_idstring uuid required

Unique identifier for the attachment

upload_urlstring uri required

Presigned URL for uploading the file. PUT the raw binary file content to this URL with the required_headers. Do not JSON-encode or multipart-wrap the body. Expires after 15 minutes. Treat the URL as opaque — the hostname depends on partner configuration and is the same across sandbox and production.

download_urlstring uri required

Stable CDN URL for the file. Use the attachment_id to reference this file in media parts when sending messages. Files on the ephemeral attachments tier — and this URL — are removed within roughly 24–48 hours of upload, independently of any message retention window.

http_method'PUT' required

HTTP method to use for upload (always PUT)

expires_atstring date-time required

When the upload URL expires (15 minutes from now)

required_headersobject required

HTTP headers that must be set on the upload request. The presigned URL is signed with these exact values — S3 will reject the upload if they don't match.

Example response

{
  "attachment_id": "abc12345-1234-5678-9abc-def012345678",
  "upload_url": "https://uploads.linqapp.com/attachments/abc12345?X-Amz-Algorithm=...",
  "download_url": "https://cdn.linqapp.com/uploads/partner-id/abc12345/photo.jpg",
  "http_method": "PUT",
  "expires_at": "2024-01-15T10:45:00Z",
  "required_headers": {
    "Content-Type": "image/jpeg",
    "Content-Length": "1024000"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.