Attachment uploads
Send attachments as files[n] parts in a multipart message, or upload them before creating the message. Pre-uploading has four steps:
- Request an upload plan.
- Send the bytes to its upload URLs.
- Complete the upload if it is multipart.
- Include its
upload_filenamewhen creating or editing a message.
Requesting an upload plan
Section titled “Requesting an upload plan”Request attachment upload URLs accepts up to 10 files. Declare each file’s ID, name, exact byte count and content type. The endpoint reference defines the fields, permissions and file size limits.
Keep the returned plan, including its upload_filename. Use the returned content_type, which FiveCord derives from the file name and which can therefore differ from the declared value. The upload_mode determines the next steps.
Upload modes
Section titled “Upload modes”| Value | Selected for | Added fields |
|---|---|---|
| singlepart1 | A declared file_size of at most 10485760 bytes | upload_url |
| multipart2 | A declared file_size above 10485760 bytes | upload_id, part_size, and parts |
1 Stored as soon as its PUT succeeds, so it is never sent to Complete attachment upload
2 Each parts entry has a one-based part_number and its own upload_url, and the array is ordered by ascending part number
Part geometry
Section titled “Part geometry”Use the part_size and parts returned in the upload plan. Every part must contain exactly part_size bytes except the last, which contains the remainder. Do not calculate a different part layout.
Transferring the bytes
Section titled “Transferring the bytes”Send PUT requests to the returned upload_url values without an Authorization header. The URLs can target storage or the upload relay. Do not rewrite their paths or query strings.
Send exactly the declared byte count. The relay returns 413 for an oversized body and 401 for a missing, invalid, or expired capability. It also returns 413 for a body above its own limit, which is 500 MiB by default.
A singlepart transfer sends the whole file with the entry’s content_type as its Content-Type header. A multipart transfer sends each part separately.
Capability lifetimes
Section titled “Capability lifetimes”| Capability | Lifetime |
|---|---|
| Direct singlepart upload URL | 5 minutes |
| Direct multipart part URL | 1 hour |
| Relay URL of either kind1 | The relay token lifetime the deployment configures, 900 seconds by default |
1 A relay expiry is exclusive, so the capability is already rejected at its expiry second
Completing a multipart upload
Section titled “Completing a multipart upload”Complete attachment upload finishes from 1 through 10 multipart uploads. Send the upload_filename and upload_id from each plan after all its parts succeed. Do not send a part list or entity tags.
Completion checks permissions and file size limits again. See the endpoint’s response table for errors. If completion aborts the upload, request a new plan and upload the file again.
Claiming the upload
Section titled “Claiming the upload”Include the upload_filename in a pre-uploaded attachment when calling Create message or Modify message. Uploading alone does not create a message or emit a Gateway event.
An upload is bound to the identity and the channel that planned it, and a key is single use. A key the authenticated identity does not own, a key planned for another channel, and a key an attachment has already consumed each return 400 INVALID_FORM_BODY with UPLOADED_ATTACHMENT_NOT_FOUND on attachments.{index}.upload_filename. Where the object is absent from storage, which is what an untransferred plan leaves behind, the claim returns the same status with FILE_NOT_FOUND on the same path.
Stream previews
Section titled “Stream previews”A stream preview is a JPEG attached to a voice connection. It uses the user-only Streams API, not the attachment flow. Follow its access rules to read or change a preview.
Use Upload stream preview to send the image as base64 in JSON. Canonical base64 uses the standard alphabet, a length divisible by four and at most two trailing = characters. Decoding and re-encoding must produce the same string. Invalid encoding returns 400 INVALID_STREAM_THUMBNAIL_PAYLOAD.
Alternatively, request an upload URL and send the JPEG with PUT. Use the returned content_type, send at most max_bytes bytes and upload before expires_at. The URL can be reused until it expires.
Send a valid JPEG of at most 1000000 bytes. Get stream preview reads it, and Delete stream preview removes it.
A preview expires one day after an inline upload or the request that issued its upload URL. Reusing the URL does not extend the preview’s lifetime. An expired preview returns an empty 404.
Failures
Section titled “Failures”API requests return the standard error response. Relay requests return plain-text media errors. Direct storage errors use the storage provider’s format.
Each API endpoint documents its rate limit. The relay has no request-count rate limit.