Skip to main content
Attachments use a two-step upload flow:
  1. Create an upload slot.
  2. PUT the bytes to upload_url.
  3. Send a chat message with a media part through POST /api/v1/chats/{id}/messages.

1. Create an upload slot

2. Upload bytes

HMAC is not supported on the binary upload route. Use bearer auth.
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 set parallel_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.
You can include 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

Use GET /api/v1/attachments/{id} to check the registered attachment.
Use 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.
Inbound images and files arrive in data.message.parts[] as media parts:

Caveats

See also