Skip to main content
The image, file, and card blocks can get their content from two places. If the file already lives somewhere public, just link to it. There is nothing to upload:

Uploading

One multipart POST. Two endpoints, same behaviour. Pick the one that matches the key you already have.
The response_url one is best mid-workflow: no API key needed, because the token already carries permission.
file
binary
required
The file part. Missing it returns 400 MALFORMED_MULTIPART.
filename
string
Replaces the file’s own name. Cut to 255 characters.
201 Created

Then use it

Blocks only store the file_id. Each time someone reads the message, we make a fresh short-lived link. Links in your JSON never go stale.

Uploading in two steps

In Make or n8n, this is two HTTP modules: upload, then map file.file_id into the message body.
1

Upload

POST the binary to {{response_url}}/files as multipart/form-data. Read back file.file_id.
2

Post the message

POST Block Kit to {{response_url}}, mapping the file_id from step 1.

What we accept

Images
10 MB max
PNG, JPEG, GIF, WebP, AVIF.
Other files
25 MB max
PDF, XLSX, DOCX, PPTX, ZIP, and anything else not blocked below.
We check the file’s real type by reading its first bytes. We never trust the name or the Content-Type. Renaming evil.exe to report.pdf does not work.
Images are converted to WebP when uploaded, and only that copy is kept. The original is thrown away. The size limit is checked against what you uploaded, not the smaller converted file.

Rejected

HTML is blocked because rich HTML belongs in Pages, not chat attachments. HEIC is refused instead of stored broken — send JPEG, PNG, or WebP instead.

Errors

Storage is reserved before we save the file. A 402 means nothing was saved and nothing was counted.