Attachments
Send files (images, videos, documents, audio) with messages by providing a URL in a media part.
Pre-uploading via POST /v3/attachments is optional and only needed for specific optimization scenarios.
Sending Media via URL (up to 10MB)
Provide a publicly accessible HTTPS URL with a supported media type in the url field of a media part.
{
"parts": [
{ "type": "media", "url": "https://your-cdn.com/images/photo.jpg" }
]
}
This works with any URL you already host — no pre-upload step required. Maximum file size: 10MB.
Pre-Upload (required for files over 10MB)
Use POST /v3/attachments when you want to:
- Send files larger than 10MB (up to 100MB) — URL-based downloads are limited to 10MB
- Send the same file to many recipients — upload once, reuse the
attachment_idwithout re-downloading each time - Reduce message send latency — the file is already stored, so sending is faster
How it works:
POST /v3/attachmentswith file metadata → returns a presignedupload_url(valid for 15 minutes) and a reusableattachment_id- PUT the raw file bytes to the
upload_urlwith therequired_headers(no JSON or multipart — just the binary content) - Reference the
attachment_idin your media part when sending messages (stays valid unless deleted — see Attachment Lifetime)
Key difference: When you provide an external url, we download and process the file on every send.
When you use a pre-uploaded attachment_id, the file is already stored — so repeated sends skip the download step entirely.
Attachment Lifetime
An attachment_id and its CDN URL stay valid until you delete the file with
DELETE /v3/attachments/{attachmentId}.
Deletion is not reversible, and there is no attachment.deleted webhook.
Domain Allowlisting
Attachment URLs in API responses are served from cdn.linqapp.com. This includes:
urlfields in media message partsdownload_urlfields in attachment and upload response objects
If your application enforces domain allowlists (e.g., for SSRF protection), add:
cdn.linqapp.com
Supported File Types
- Images: JPEG, PNG, GIF, HEIC, HEIF, TIFF, BMP
- Videos: MP4, MOV, M4V
- Audio: M4A, AAC, MP3, WAV, AIFF, CAF, AMR
- Documents: PDF, TXT, RTF, CSV, Office formats, ZIP
- Contact & Calendar: VCF, ICS
File Size Limits
- URL-based (
urlfield): 10MB maximum - Pre-upload (
attachment_id): 100MB maximum
Security & Ownership
Every attachment is bound to the partner account that created or received it. The API enforces ownership on every operation that touches an attachment — sending, retrieving, deleting.
What this means for you:
- An attachment created under your API key can only be referenced by your API key.
- Submitting another partner’s
attachment_idreturns404 Not Found. We do not disclose whether the id exists or belongs to someone else. - Submitting a CDN URL that resolves to another partner’s attachment is rejected before the send is attempted.
- Ownership enforcement applies uniformly across send, create-chat, retrieve, and delete operations.
Every attachment-affecting endpoint requires a valid partner API key. Unauthenticated calls return 401 Unauthorized.
Attachment URL Patterns
Attachment URLs in API responses and webhook payloads use this layout:
https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}
The URL itself does not expire, but see Attachment Lifetime.
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
Deleting an Attachment
To permanently remove an attachment you own, use:
DELETE /v3/attachments/{attachmentId}
Authorization: Bearer <your_api_key>
What this does:
- Verifies the attachment is owned by your account. Returns
404otherwise. - Removes the underlying file from Linq storage.
- Records an audit entry (timestamp, partner, attachment id).
Response codes:
| Status | Meaning |
|---|---|
204 No Content | Deletion succeeded. The attachment is removed from Linq storage. |
400 Bad Request | attachmentId is not a valid UUID. |
401 Unauthorized | Missing or invalid API key. |
404 Not Found | Attachment does not exist or is not owned by your account. |
500 Internal Server Error | Transient infrastructure issue — safe to retry. |
Effect on message history:
- Messages that referenced the deleted attachment remain visible.
- The message part that pointed at the attachment is preserved with no attachment reference.
- Webhook payloads previously delivered to you retain the original URL string, but downloads from that URL return
404going forward.
Deletion is irreversible. Once 204 is returned, the bytes are gone — there is no undelete.
Inbound Media Flow
When one of your phone numbers receives a message with media (image, video, audio, document), the platform:
- Stores the file under your partner account.
- Records metadata linked to the inbound message.
- Delivers a webhook whose
parts[]array includes amediapart with aurlpointing atcdn.linqapp.com.
You can acknowledge the webhook without fetching the file inline, and lazy-load via GET /v3/attachments/{attachmentId} later.
Data Lifecycle Summary
| Data | Retention |
|---|---|
| Attachment bytes | Retained until you DELETE |
| Attachment metadata (id, filename, mime type, size) | Retained until you DELETE |
| Message body & parts | Retained per message-retention policy |
| Audit log of deletions | Retained per platform retention policy |
In transit: TLS 1.2+ everywhere. At rest: AES-256 (server-side encryption).
Compliance Checklist
If you’re integrating Linq under a security or privacy review, here is the short list:
- Allowlist exactly one outbound domain:
cdn.linqapp.com. - Implement
DELETE /v3/attachments/{attachmentId}calls in your deletion workflow. - For audit: every deletion is logged on Linq’s side. Surface a confirmation in your application UI based on the
204response. - For end-user “right to delete” requests: enumerate attachment ids and
DELETEeach. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.