- Create an upload slot.
- PUT the bytes to
upload_url. - Send a chat message with a
mediapart throughPOST /api/v1/chats/{id}/messages.
To send audio as a native iMessage voice-note bubble, use the separate
Voice notes workflow. Do not upload it here or put a
voice_note_id in attachments[]; generic audio attachments may render as
ordinary files or media attachments. You can submit an ordinary uncompressed
WAV to the voice-note endpoint; Chert performs the compatible Opus-in-CAF
conversion server-side.1. Create an upload slot
2. Upload bytes
Single PUTs accept up to 100 MB per file. Chert streams the body straight through to storage — there is no in-memory buffering bottleneck, so large uploads scale with your network throughput. Set
Content-Length on the PUT so we can fast-reject a body that exceeds the size you registered.3. Send the attachment
Send multiple images as one bubble
For multiple uploaded media parts that should arrive as one grouped delivery rather than N back-to-back bubbles, send a normal chat message and setparallel_attachments: true. Chert requests grouped delivery; Apple devices decide the final collage, stack, or attachment presentation.
The shape is the same parts[] you use for every other chat send. The only difference is the top-level parallel_attachments: true flag.
parallel_attachments on the first touch too — POST /api/v1/chats accepts it inside message.
Rules
Errors
Supported uploads
The public API validates the declared file size and rejects unsupported MIME types. Upload slots expire after 15 minutes.
Metadata and download
UseGET /api/v1/attachments/{id} to check the registered attachment.
GET /api/v1/attachments/{id}/content to stream the binary content. This works for attachments you uploaded and for inbound media ids received in message.received webhooks.
data.message.parts[] as media parts:
filename or
size_bytes, and mime_type may be the generic
application/octet-stream. The authenticated content response can provide a
more useful filename in Content-Disposition; inspect the downloaded file
signature and media metadata rather than trusting the webhook MIME type alone.
Apple voice memos use this normal inbound attachment flow—there is no separate
inbound voice-note endpoint. A verified recording downloaded as
Audio_Message.caf, a playable CAF container with Opus audio, even though its
event MIME type was application/octet-stream and the event did not include a
filename. This observed CAF/Opus combination is not guaranteed across every
device or OS version. See Receiving inbound voice memos.

