---
title: "Upload a media file"
method: POST
path: "/media/upload"
tags: ["Media"]
---

# Upload a media file

`POST /media/upload`

## Request

- Base URL: `https://api.cavuno.com/v1`
- URL: `https://api.cavuno.com/v1/media/upload`
- Auth: HTTP bearer

Uploads a file via the unified media dispatcher. Send a multipart form with `file` (binary) and `purpose` (one of `board_logo`, `board_hero`, `account_avatar`, `company_logo`, or `blog_image`). Optionally include `resourceType` and `resourceId` to bind the upload to an owning resource. The request is idempotent when an `Idempotency-Key` header is supplied.

## Response `201`

Successful response.

- MediaUpload
  - `id` string, required: Unique identifier for the object. Use this value as the `{id}` path parameter for `GET /v1/media/{id}`.
  - `object` 'media_upload', required: String representing the object's type. Objects of the same type share the same value.
  - `url` string, nullable, required: URL where the file can be downloaded. Permanent for files served from the assets domain; a signed URL for legacy files. Always set on the upload response; may be `null` on retrieval if the underlying blob has been deleted.
  - `urlExpiresAt` string, nullable, required: Time at which the signed `url` expires (ISO 8601 datetime), or `null` when the `url` is permanent and never expires.
  - `mimeType` string, required: MIME type of the uploaded file.
  - `sizeBytes` number, required: Size of the uploaded file, in bytes.
  - `purpose` 'board_logo' | 'board_hero' | 'account_avatar' | 'company_logo' | 'blog_image', required: Resource type the file was uploaded for.

## Other responses

- `400`: The `purpose` field is invalid, or the request was otherwise malformed.
- `403`: The caller lacks the permission required for the requested upload purpose.
- `404`: The owning resource for the upload (`resourceId`) does not exist.
- `413`: The uploaded file exceeded the 5 MB size limit.
- `415`: The uploaded file's MIME type is not supported.
- `429`: Too many uploads. The limit is 30 per minute per account.

## Changes

- **2026-10-19** `c34152c38176`: 6 info
  - added the optional property `error/upgrade` to the response with the `400` status
  - added the optional property `error/upgrade` to the response with the `403` status
  - added the optional property `error/upgrade` to the response with the `404` status
  - added the optional property `error/upgrade` to the response with the `413` status
  - …2 more

[Operation history](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/changes/media/upload/post.md)

---

[API](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api.md) · [All operations](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/revisions/d5974dabff14?raw)
