> ## Documentation Index
> Fetch the complete documentation index at: https://info.bundle.social/llms.txt
> Use this file to discover all available pages before exploring further.

# Media Upload

> Upload images, videos, and documents with small or large upload flows.

## Overview

You have two ways to upload files.

1. **Simple Upload:** Quick, easy, for small stuff.
2. **Resumable Upload:** Robust, 3-step process, for big videos.

<Warning>
  **Recommendation:** Always use the **Resumable Upload** for videos. It's more reliable. If a 5GB upload fails at 99% with the Simple method, you start over. With Resumable, you don't.
</Warning>

***

## Method 1: Resumable Upload (The Pro Way)

Ideal for videos or anything >25MB.

### Step 1: Initialize

Tell us what you're planning to upload.

**Endpoint:** `POST /api/v1/upload/init`

```json theme={null}
// Request
{
  "fileName": "viral-video.mp4",
  "mimeType": "video/mp4",
  "teamId": "..." // optional
}
```

**Response:**
We give you a magic `url` (Pre-signed URL) and a `path`. Keep them safe.

```json theme={null}
{
  "url": "https://storage.googleapis.com/...",
  "path": "uploads/123/viral-video.mp4"
}
```

<Note>
  **The pre-signed URL expires after 30 minutes.** If you don't start uploading within that window, you'll need to initialize again.
</Note>

### Step 2: Push the Bytes

Send the raw binary file to the `url` we gave you. Use `PUT`.

<Note>
  **Important:** Do not wrap this in JSON or Multipart form. Just send the raw bytes.
</Note>

```bash theme={null}
curl -X PUT "https://storage.googleapis.com/..." \
  --upload-file ./viral-video.mp4
```

### Step 3: Finalize

Tell us you're done so we can register the file in our system.

**Endpoint:** `POST /api/v1/upload/finalize`

```json theme={null}
// Request
{
  "path": "uploads/123/viral-video.mp4", // from Step 1
  "teamId": "..."
}
```

**Response:**
You get an `id` (e.g., `upload_abc123`). **This is the ID you use when creating a post.**

***

## Method 2: Simple Upload (The Lazy Way)

Good for images or small clips. Uses standard `multipart/form-data`.

**Endpoint:** `POST /api/v1/upload`

```bash theme={null}
curl -X POST "https://api.bundle.social/api/v1/upload" \
  -H "x-api-key: YOUR_KEY" \
  -F "file=@./meme.jpg" \
  -F "teamId=YOUR_TEAM_ID"
```

**Response:**
Returns the `id` immediately.

***

## Upload from a URL

Register media by passing a **public HTTP(S) URL** instead of uploading the bytes yourself: `POST /api/v1/upload/from-url` (also exposed in the SDKs and the MCP server). We fetch the asset **server-side** and register it like any other upload.

| Detail           | Value                                                                                                                                                                                                 |
| :--------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Max size         | **1 GB**                                                                                                                                                                                              |
| Download timeout | **60 seconds**                                                                                                                                                                                        |
| Best for         | Small / medium files (typical short-form / feed content)                                                                                                                                              |
| Not for          | Large videos — we fetch the file server-side and cap it at **1 GB / 60 s**. For bigger files, upload the bytes yourself with [Resumable Upload](#method-1-resumable-upload-the-pro-way) (up to 5 GB). |

<Note>
  The **1 GB / 60 s** limit applies only to URL imports, because we download the file for you. Direct uploads (Simple / Resumable) stream straight to storage and allow up to **5 GB**.
</Note>

***

## Supported Formats & Limits

| Type          | Formats       | Max Size                                                 |
| :------------ | :------------ | :------------------------------------------------------- |
| **Images**    | JPG, PNG, GIF | 25 MB                                                    |
| **Videos**    | MP4, MOV      | Platform-dependent (see [Limits](/api-reference/limits)) |
| **Documents** | PDF           | 100 MB                                                   |

<Note>
  The overall upload ceiling is **5 GB** per file; the max video size also depends on the platform you're posting to. TikTok allows up to 1 GB, YouTube up to 5 GB, while Discord caps at 10 MB. Check [Platform Limits](/api-reference/limits) for the exact numbers per platform.
</Note>

<Info>
  **Tip:** If you are uploading a picture of your cat (or your mom, we don't judge), Simple Upload is fine. For a 4K podcast clip, use Resumable.
</Info>

***

## Video Compression

You can enable automatic video compression on your organization. When enabled, we'll compress videos larger than 10 MB before they're stored and posted.

### How to enable

Video compression is an organization-level setting. You can toggle it from your dashboard or contact us to enable it. Once on, it applies to all uploads across all teams in your org.

### What happens

| Setting       | Value                                     |
| :------------ | :---------------------------------------- |
| Threshold     | Videos > 10 MB                            |
| Output format | MP4 (H.264 + AAC)                         |
| Quality       | CRF 30 (good balance of quality and size) |
| Preset        | Medium                                    |

We're smart about it - if the compressed file ends up **larger** than the original (rare, but it happens with already-compressed videos), we keep the original and toss the compressed version. You always get the smaller file.

<Tip>
  This is great if your users upload raw or minimally compressed videos. A 500 MB screen recording can often shrink to under 100 MB with no visible quality loss. Your storage costs will thank you - and so will the upload speeds.
</Tip>
