---
title: "Upload image for sequence messages"
description: "Upload an image file to Cloudflare R2 storage for use in SMS sequences.\nSupports JPEG, PNG, GIF, and WebP formats up to 10MB.\nImages are organized by workspace for security and isolation.\n"
---

> Documentation Index
> Fetch the complete documentation index at: https://developer.channelautomations.com/llms.txt
> Use this file to discover all available pages before exploring further.

Path: Channel Automation API › Media

`POST /api/media/upload`

Upload an image file to Cloudflare R2 storage for use in SMS sequences.
Supports JPEG, PNG, GIF, and WebP formats up to 10MB.
Images are organized by workspace for security and isolation.

## Authentication

Requires one of the following:

- `bearerAuth`
- `apiKey`

## Request body

_Required._

- `image` (`post/api/media/upload.image`; string, required) — Image file to upload
  - format `binary`
- `workspaceId` (`post/api/media/upload.workspaceId`; string, required) — Workspace ID
  - example `"workspace-123"`

## Example request

```text
{
  "image": "<image>",
  "workspaceId": "workspace-123"
}
```

## Code samples

### cURL

```bash
curl --request POST \
  --url https://api.channelautomation.com/api/media/upload \
  --form 'image=@<image>;type=application/octet-stream' \
  --form-string 'workspaceId=workspace-123'
```

### TypeScript

```typescript
import { readFile } from 'node:fs/promises';

const formData = new FormData();
formData.append('image', new Blob([await readFile('<image>')]), '<image>');
formData.append('workspaceId', 'workspace-123');

const url = 'https://api.channelautomation.com/api/media/upload';
const options = {method: 'POST', body: formData};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://api.channelautomation.com/api/media/upload"

files = [
    ("image", ("<image>", open("<image>", "rb"), "application/octet-stream"))
]
payload = { "workspaceId": "workspace-123" }

response = requests.post(url, data=payload, files=files)

print(response.text)
```

## Responses

### 200

Image uploaded successfully

#### Example

```json
{
  "success": true,
  "url": "https://image.customerconnects.app/sequences/workspace123/abc123-def456.jpg",
  "fileName": "sequences/workspace123/abc123-def456.jpg",
  "originalName": "image.jpg",
  "size": 1024000
}
```

- `success` (`post/api/media/upload.response.200.success`; boolean, optional)
- `url` (`post/api/media/upload.response.200.url`; string, optional) — Public URL of uploaded image
- `fileName` (`post/api/media/upload.response.200.fileName`; string, optional)
- `originalName` (`post/api/media/upload.response.200.originalName`; string, optional)
- `size` (`post/api/media/upload.response.200.size`; number, optional)

### 400

Bad request or validation error

#### Example

```json
{
  "success": false,
  "error": "No image file provided"
}
```

- `success` (`post/api/media/upload.response.400.success`; boolean, optional)
  - example `false`
- `error` (`post/api/media/upload.response.400.error`; string, optional) — Error message

### 500

Server error

#### Example

```json
{
  "success": false,
  "error": "Failed to upload image"
}
```

- `success` (`post/api/media/upload.response.500.success`; boolean, optional)
  - example `false`
- `error` (`post/api/media/upload.response.500.error`; string, optional) — Error message


Source: https://developer.channelautomations.com/api/post-api-media-upload/index.md
