---
title: "Request presigned attachment upload URLs"
method: POST
path: "/channels/{channel_id}/attachments"
tags: ["Channels", "Messages"]
---

# Request presigned attachment upload URLs

`POST /channels/{channel_id}/attachments`

Returns presigned upload URLs for message attachments in the target channel. Small files (<=10MB) return a singlepart PUT URL; larger files return a multipart plan (upload_id + per-part URLs) that the client should complete via the matching /attachments/complete endpoint. Requires message send and attachment permissions in guild channels.

## Path parameters

- `channel_id` string, snowflake, required

## Request body

- PresignedAttachmentUploadRequest
  - `attachments` PresignedAttachmentUploadRequestItem[], required — Attachment upload specifications
    - `id` integer, required
    - `filename` string, required — The name of the file that will be uploaded
    - `file_size` integer, required
    - `content_type` string, required — MIME type the client will upload

## Response `200`

Success

- PresignedAttachmentUploadResponse
  - `attachments` PresignedAttachmentUploadResponseItem[], required — Presigned upload details for each attachment
    - union
      - SinglepartPresignedAttachmentUploadResponseItem
        - `id` integer, required
        - `filename` string, required — The original filename for this upload
        - `upload_filename` string, required — Temporary upload key to reference in message send payloads
        - `file_size` integer, required
        - `content_type` string, required — Expected MIME type for this upload
        - `upload_mode` 'singlepart', required
        - `upload_url` string, required — Presigned URL used to upload this attachment with a single PUT
      - MultipartPresignedAttachmentUploadResponseItem
        - `id` integer, required
        - `filename` string, required — The original filename for this upload
        - `upload_filename` string, required — Temporary upload key to reference in message send payloads
        - `file_size` integer, required
        - `content_type` string, required — Expected MIME type for this upload
        - `upload_mode` 'multipart', required
        - `upload_id` string, required — S3 multipart upload identifier; required to complete the upload
        - `part_size` integer, required
        - `parts` object[], required — Per-part presigned URLs for parallel upload
          - `part_number` integer, required
          - `upload_url` string, required — Presigned URL used to upload this part

## Other responses

- `400` — Bad Request - The request was malformed or contained invalid data
- `401` — Unauthorized - Authentication is required or the token is invalid
- `403` — Forbidden - You do not have permission to perform this action
- `429` — Too Many Requests - You are being rate limited
- `500` — Internal Server Error - An unexpected error occurred

## Changes

- **2026-09-03** `fa36b1b48ca5` — 20 info
  - removed the `INVALID_PACK_TYPE` enum value from the `code` response property for the response status `400`
  - removed the `INVALID_PACK_TYPE` enum value from the `code` response property for the response status `401`
  - removed the `INVALID_PACK_TYPE` enum value from the `code` response property for the response status `403`
  - removed the `INVALID_PACK_TYPE` enum value from the `code` response property for the response status `500`
  - …16 more

[Change history](https://skmtc.dev/fluxer/apis/fluxer-api/changes/channels/:channel_id/attachments/post.md)

---

[API](https://skmtc.dev/fluxer/apis/fluxer-api.md) · [All operations](https://skmtc.dev/fluxer/apis/fluxer-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/fluxer/fluxer-api/revisions/f6d51a9b1034/schema)
