> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/datasets/create-and-upload/adding-data.md).

# Upload Images, Videos, and Annotations

Upload images, videos, and annotations to Roboflow.

The first step to training and deploying a model with Roboflow is to upload data to a Project.

First, you will need to [create a Project](/datasets/create-and-upload/create-a-project.md).

Then, you will be taken to a web page from which you can upload data. You can also access this page from the "Upload Data" button available in your project sidebar.

## How to Add Data

You can add data to your Roboflow account by:

* Using the web application: Recommended for datasets with fewer than 1,000 images.
* Using the command line: Recommended for datasets with greater than 1,000 images.
* Using the Dataset Upload Workflow Block: Recommended for collecting data from Workflows with a model already in production.

{% hint style="info" %}
If your images already live in cloud storage such as AWS S3, Google Cloud Storage, or Azure Blob Storage, use [Datasources](/datasets/create-and-upload/adding-data/datasources.md) and Bucket Mirror as the default path instead of scripting an upload. A Datasource imports, ingests, and syncs images and metadata into your workspace automatically. Use signed URL uploads or local downloads only for one-time or ad hoc imports.
{% endhint %}

From the web application and command line, you can upload:

* JPG, PNG, WEBP, AVIF, BMP, and HEIC/HEIF images.\*
* MOV and MP4 videos.
* PDF files.
* Annotations in any of the [40+ supported formats](https://roboflow.com/formats). The formats you can use depend on your Project type.

\**Max size of 30 MB, 16,384 pixels per side, and 178,956,970 pixels (about 179 megapixels) in total.*

You can only upload annotations with their associated images. You cannot upload annotations for images that have already been imported into your dataset.

<details>

<summary>How file names are processed</summary>

Roboflow standardizes class names at upload, import, and export:

* Leading and trailing whitespace is trimmed.
* All whitespace (including newlines and tabs) becomes a space.
* Double spaces are removed.
* `/.[]#~*` characters are replaced with a dash (`-`).
* `|'"` characters are removed.

</details>

## Web App

Drag and drop images, videos, and annotations onto the Upload Data page, or onto the upload box you see when you create a Project.

<figure><img src="https://2252499186-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNVfRxNsvCh4GOyqrjmzX%2Fuploads%2Fgit-blob-deb24c5aa34b10e1ccab8bec61e7f55ed2f8c273%2Fimage%20(426).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Upload a Zip File

A `.zip` archive of up to 300 files extracts in your browser and goes through the same flow as a dropped folder, keeping any nested folders. A larger archive (up to 8 GB) uploads as one file and is processed on Roboflow's servers. Once the upload bar finishes, you can keep working and follow progress in your Activity Center. The images appear in a batch on your Annotate page. For archives over 8 GB, use the [CLI](#cli).

By default, images already in the Project keep their annotations. To replace them with the ones in the zip, check "Replace annotations on images already in this project" in the confirmation dialog. Classification Projects always replace the label.

If the archive includes annotations, its images land in a new annotation job credited to you, even when you upload the same zip again. With [Review Mode](/datasets/annotate/annotate/team-collaboration.md#review-mode) on, they wait in Review until a reviewer approves them. With it off, they join your dataset right away.

### Upload Video

Image-based Projects split each video into frames you annotate. Action Recognition Projects keep each video intact so you can label actions as [video segments](/datasets/annotate/annotate/annotate-video-segments.md).

The extraction dialog samples frames at an interval from 60 frames per second down to 1 frame every 60 seconds. Drag the trim handles on the filmstrip to exclude frames outside a range. To pick frames by hand, click "Manual selection", then press `M` to add the current frame, `,` and `.` to step one frame, and `Shift+Left` and `Shift+Right` to jump between selected frames. Sampled and selected frames are merged without duplicates.

When you queue several videos, you can apply the same interval to all of them. Selected frames belong to one video, so each video with selected frames opens its own dialog.

<details>

<summary>Supported video file formats</summary>

Roboflow decodes videos with your browser, so the formats you can upload depend on [your browser's video support](https://caniuse.com/?search=video%20format). MOV and MP4 work in most browsers.

If your browser can't decode a video, Roboflow shows an "unsupported video" error. HEVC/H.265 is a common cause (ex: footage from DJI drones, GoPros, and newer phones) and only Safari decodes it. Convert the video to MP4 (H.264) and upload it again.

If a video still won't load, post on the [forum](https://discuss.roboflow.com/) or contact your account representative.

</details>

### Import Video Segment Annotations

Action Recognition projects can import labels that say when each action happens. Drag in a folder of videos with one `_annotations.coco.json` beside each video it describes:

```
my_videos/
├── train/
│   ├── serve-01.mp4
│   └── _annotations.coco.json
└── valid/
    ├── serve-02.mp4
    └── _annotations.coco.json
```

Each file sets `info.format` to `roboflow-video-coco` and describes one MP4 or MOV video. Spatial and per-frame annotations are skipped, and zip archives are not accepted. A folder named `train`, `valid`, or `test` sets the split of the videos inside it. Otherwise you pick the split before the upload starts.

Importing a video again replaces its segments, unless it already has frame annotations, which Roboflow keeps instead.

## HTTP API

### Upload a Video

Upload MP4 or MOV videos up to 3 GB to your Workspace, or to a Project such as an Action Recognition Project. An upload takes three steps:

1. Prepare the upload. You get a `videoId`, a `signedUrl`, and `requiredHeaders`.
2. Send the video file with a `PUT` request to `signedUrl`, with every header in `requiredHeaders`. The URL expires after 60 minutes.
3. Read the upload status until `status` is `uploaded` or `failed`.

The optional `batch`, `tag`, `metadata`, and `split` fields work like they do for image uploads. If the same video is already in the Project, Roboflow reuses it. The video keeps its batch and gets your tags, metadata, and split.

{% openapi src="/files/rpreUGJFoVCNTx5C4X8n" path="/{workspace}/upload/video" method="post" %}
[video-upload.yaml](https://2252499186-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNVfRxNsvCh4GOyqrjmzX%2Fuploads%2Fgit-blob-fd03929d0d9fea85d103811eda7c4269428be525%2Fvideo-upload.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/rpreUGJFoVCNTx5C4X8n" path="/{workspace}/upload/video/{videoId}" method="get" %}
[video-upload.yaml](https://2252499186-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNVfRxNsvCh4GOyqrjmzX%2Fuploads%2Fgit-blob-fd03929d0d9fea85d103811eda7c4269428be525%2Fvideo-upload.yaml?alt=media)
{% endopenapi %}

To find uploaded videos, [search the dataset](/datasets/manage/manage-datasets/dataset-search.md#http-api) with `mediaTypes` set to `["video"]`.

## CLI

You can upload larger datasets using the Roboflow Python command line interface.

You can only upload images with the command line interface. If you have videos, you will need to [split them into frames saved as files](https://superuser.com/questions/1044444/how-do-i-use-ffmpeg-to-split-a-video-into-images-and-then-reassemble-exactly-the). These files can then be uploaded to Roboflow.

To get started, first install `roboflow-python`:

```
pip install roboflow
```

Next, [retrieve your Workspace ID](https://docs.roboflow.com/reference/authentication/authentication/workspace-and-project-ids).

Finally, prepare a command in the following format:

```
roboflow import -w testupload -p project-1-8zgld /path/to/dataset/folder
```

Here are the arguments you need to specify:

* `-w testupload`: This is the workspace name.
* `-p <project-id>`: This is your project ID.

When you run the command, you will see a message that indicates the upload process has started. You will then see logs as images upload:

<figure><img src="https://2252499186-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNVfRxNsvCh4GOyqrjmzX%2Fuploads%2Fgit-blob-cb3c6b1fff1fa6883a6fb226f8a3704493263a70%2FCleanShot%202024-03-13%20at%2011.29.09%402x.png?alt=media" alt=""><figcaption><p>Uploading a dataset using the command-line</p></figcaption></figure>

We have a video walkthrough that shows how to upload data from the command line:

{% embed url="<https://www.loom.com/share/19637984033a466b831af56f9404fa89>" %}

### Upload a Zip File

For large datasets, you can upload a single `.zip` archive of your images and annotations instead of individual files. The archive is uploaded once and processed asynchronously on Roboflow's servers, which is faster and more reliable than uploading file by file.

Upload a `.zip` directly:

```bash
roboflow image upload dataset.zip --workspace <workspace> -p <project>
```

Or let the CLI zip a folder for you before uploading:

```bash
roboflow image upload ./dataset/folder --zip-upload --workspace <workspace> -p <project>
```

By default the command waits for processing to finish and prints a summary. Pass `--no-wait` to return immediately; the CLI prints a task ID you can use to poll the upload status.

## Python SDK

Use `Workspace.upload_dataset()` to upload a `.zip` archive or zip a folder before upload:

```python
import roboflow

rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
workspace = rf.workspace()

# A .zip path is detected automatically and uploaded as an archive
workspace.upload_dataset("dataset.zip", project_name="your-project")

# For a folder, opt in with use_zip_upload to zip and upload it as one archive
workspace.upload_dataset("./dataset/folder", project_name="your-project", use_zip_upload=True)
```

{% hint style="info" %}
Zip upload supports archives up to 8 GB and 100,000 files. Predictions (`is_prediction=True`) are not supported on the zip path - use the per-image upload for those.
{% endhint %}

## MCP Server

Connect your AI agent to the [MCP Server](https://docs.roboflow.com/agents/mcp-server) and it can add images to a project with these tools:

<table data-search="false"><thead><tr><th width="290">Tool</th><th>Description</th></tr></thead><tbody><tr><td><code>image_upload</code></td><td>Upload local image files to a project via a zip.</td></tr><tr><td><code>image_upload_status</code></td><td>Check the status of an image zip upload task.</td></tr><tr><td><code>images_update_metadata</code></td><td>Update metadata and tags on an uploaded image.</td></tr></tbody></table>

## View Your Uploaded Data

All data uploaded to Roboflow is uploaded in a "batch". These batches can be viewed on your Project Annotate page:

<figure><img src="https://2252499186-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNVfRxNsvCh4GOyqrjmzX%2Fuploads%2Fgit-blob-e02e3663f94fef52256a1528c2361066bcc4d89f%2FScreenshot%202025-05-20%20at%2008.04.10.png?alt=media" alt=""><figcaption></figcaption></figure>

## Image Size limits

An image can be at most 30 MB, at most 16,384 pixels on each side, and at most 178,956,970 pixels (about 179 megapixels) in total. Every upload method refuses a larger image, including the web app, the API, zip uploads, and Datasources. Images uploaded before these limits stay in your Project.

## Duplicate Images

If you try to upload an image that is already in a Project, upload for that image will be skipped.

Removing an image from a Project keeps its annotations. If you upload that image again, it rejoins the Project with those annotations and its old annotation status, so an annotated image does not come back as unannotated.

{% hint style="info" %}
If you [merge two datasets](/datasets/manage/merge-datasets.md), the merged dataset and the two original datasets exist in your account. Therefore, there is no charge for the merge, because the images are duplicates.
{% endhint %}

## Data Ownership

You retain ownership over all images and videos you upload to Roboflow. This is defined in [our Section 23B of our Terms of Service](https://roboflow.com/terms):

> You retain all ownership rights in any content, information, or materials You post, submit, publish, display, or transmit

## Data Privacy

Private projects are not publicly listed on Roboflow Universe. You can [control project privacy](/datasets/manage/make-a-project-public.md).
