Upload API
Adding images to your datasets via the web UI is preferred when possible because it is more fully-featured and you can import and validate annotations from other tools. But it can be useful to use our API to collect real-world images directly from your application to improve your model.

Upload with Roboflow's Python Package

This is the recommended method for the programmatic upload of images and Video to your Roboflow projects.
Upload Images
Upload Video

Installing the Python Package

pip install roboflow

Uploading Images with Roboflow Python Package

# importing the roboflow Python Package
from roboflow import Roboflow
# creating the Roboflow object
# obtaining your API key: https://docs.roboflow.com/rest-api#obtaining-your-api-key
rf = Roboflow(api_key="YOUR_PRIVATE_API_KEY")
# using the workspace method on the Roboflow object
workspace = rf.workspace()
# identifying the project for upload
project = workspace.project("YOUR_PROJECT_ID")
# uploading the image to your project
project.upload("UPLOAD_IMAGE.jpg")
# if you want to attempt reuploading image on failure
# project.upload("UPLOAD_IMAGE.jpg", num_retry_uploads=3)
This method requires ffmpeg and the roboflow PIP package.

Active Learning with the Python Package

Upload API Parameters (Images)

post
https://api.roboflow.com
/dataset/:url/upload
Upload Image

Code Snippets

For your convenience, we've provided code snippets for calling this endpoint in various programming languages. If you need help integrating the upload API into your project don't hesitate to reach out.
All examples upload to an example dataset with an identifier of your-dataset. You can easily find your dataset's identifier by looking at the URL when you're in the Roboflow web interface.
cURL
Python
Javascript
iOS
Android & Java
Ruby
PHP
Go
.NET
Elixir

Linux or macOS

Uploading a local file called YOUR_IMAGE.jpg using multipart/form-data (recommended):
curl -F name=YOUR_IMAGE.jpg -F split=train \
-F [email protected]_IMAGE.jpg \
"https://api.roboflow.com/dataset/YOUR_DATASET_NAME/upload?\
api_key=YOUR_API_KEY"
Alternatively, uploading a base64 encoded image:
base64 YOUR_IMAGE.jpg | curl -d @- \
"https://api.roboflow.com/dataset/your-dataset/upload?\
api_key=YOUR_API_KEY&\
name=YOUR_IMAGE.jpg&\
split=train"
Uploading an image hosted on the web via its URL (don't forget to URL encode it):
curl -X POST "https://api.roboflow.com/dataset/your-dataset/upload?\
api_key=YOUR_API_KEY&\
image=https%3A%2F%2Fi.imgur.com%2FPEEvqPN.png&\
name=201-956-1246.png&\
split=train"

Windows

You will need to install curl for Windows and GNU's base64 tool for Windows. The easiest way to do this is to use the git for Windows installer which also includes the curl and base64 command line tools when you select "Use Git and optional Unix tools from the Command Prompt" during installation.
Then you can use the same commands as above.

Uploading a Local Image

To install dependencies, pip install requests pillow requests-toolbelt
import requests
import base64
import io
from PIL import Image
from requests_toolbelt.multipart.encoder import MultipartEncoder
# Load Image with PIL
image = Image.open("YOUR_IMAGE.jpg").convert("RGB")
# Convert to JPEG Buffer
buffered = io.BytesIO()
image.save(buffered, quality=90, format="JPEG")
# Construct the URL
upload_url = "".join([
"https://api.roboflow.com/dataset/YOUR_DATASET_NAME/upload",
"?api_key=YOUR_API_KEY"
])
m = MultipartEncoder(fields={'file': ("YOUR_IMAGE.jpg", buffered.getvalue(), "image/jpeg")})
r = requests.post(upload_url, data=m, headers={'Content-Type': m.content_type})
# Output result
print(r.json())
import requests
import base64
import io
from PIL import Image
# Load Image with PIL
image = Image.open("YOUR_IMAGE.jpg").convert("RGB")
# Convert to JPEG Buffer
buffered = io.BytesIO()
image.save(buffered, quality=90, format="JPEG")
# Base 64 Encode
img_str = base64.b64encode(buffered.getvalue())
img_str = img_str.decode("ascii")
# Construct the URL
upload_url = "".join([
"https://api.roboflow.com/dataset/your-dataset/upload",
"?api_key=YOUR_API_KEY",
"&name=YOUR_IMAGE.jpg",
"&split=train"
])
# POST to the API
r = requests.post(upload_url, data=img_str, headers={
"Content-Type": "application/x-www-form-urlencoded"
})
# Output result
print(r.json())

Adding an Image Hosted Elsewhere via URL

import requests
import urllib.parse
# Construct the URL
img_url = "https://i.imgur.com/PEEvqPN.png"
upload_url = "".join([
"https://api.roboflow.com/dataset/your-dataset/upload",
"?api_key=YOUR_API_KEY",
"&name=201-956-1246.png",
"&split=train",
"&image=" + urllib.parse.quote_plus(img_url)
])
# POST to the API
r = requests.post(upload_url)
# Output result
print(r.json())

How To Upload an Image with the API (Python)

We also have a video demonstration of using the Upload API with Python:
Uploading images and annotations with Python

Node.js

We're using axios and form-data to perform the POST request in this example so first run npm install axios form-data to install the dependency.
const axios = require("axios");
const fs = require("fs");
const FormData = require('form-data');
const formData = new FormData();
formData.append("name", "YOUR_IMAGE.jpg");
formData.append("file", fs.createReadStream("YOUR_IMAGE.jpg"));
formData.append("split", "train");
axios({
method: "POST",
url: "https://api.roboflow.com/dataset/YOUR_DATASET_NAME/upload",
params: {
api_key: "YOUR_API_KEY"
},
data: formData,
headers: formData.getHeaders()
})
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error.message);
});
const axios = require("axios");
const fs = require("fs");
const image = fs.readFileSync("YOUR_IMAGE.jpg", {
encoding: "base64"
});
axios({
method: "POST",
url: "https://api.roboflow.com/dataset/YOUR_DATASET_NAME/upload",
params: {
api_key: "YOUR_API_KEY",
name: "YOUR_IMAGE.jpg",
split: "train"
},
data: image,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error.message);
});

Adding an Image Hosted Elsewhere via URL

const axios = require("axios");
axios({
method: "POST",
url: "https://api.roboflow.com/dataset/YOUR_DATASET_NAME/upload",
params: {
api_key: "YOUR_API_KEY",
image: "https://i.imgur.com/PEEvqPN.png",
name: "201-956-1246.png",
split: "train"
}
})
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error.message);
});

Web

We are currently beta testing roboflow.js, a browser-based JavaScript library which, among other things, includes safe client-side uploads without exposing your secret API Key to the web. If you'd like early access, please contact us.
We are adding code snippets as they are requested by users. If you'd like to integrate the upload API into your iOS app, please click below to record your upvote.

Swift

Objective C

Kotlin

Uploading with base64 encoded image:

import java.io.*
import java.net.HttpURLConnection
import java.net.URL
import java.nio.charset.StandardCharsets
import java.util.*
fun main() {
// Get Image Path
val filePath = System.getProperty("user.dir") + System.getProperty("file.separator") + "YOUR_IMAGE.jpg"
val file = File(filePath)
// Base 64 Encode
val encodedFile: String
val fileInputStreamReader = FileInputStream(file)
val bytes = ByteArray(file.length().toInt())
fileInputStreamReader.read(bytes)
encodedFile = String(Base64.getEncoder().encode(bytes), StandardCharsets.US_ASCII)
val API_KEY = "" // Your API Key
val DATASET_NAME = "your-dataset" // Set Dataset Name (Found in Dataset URL)
// Construct the URL
val uploadURL = "https://api.roboflow.com/dataset/" +
DATASET_NAME + "/upload" +
"?api_key=" + API_KEY +
"&name=YOUR_IMAGE.jpg" +
"&split=train"
// Http Request
var connection: HttpURLConnection? = null
try {
// Configure connection to URL
val url = URL(uploadURL)
connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded")
connection.setRequestProperty("Content-Length",
Integer.toString(encodedFile.toByteArray().size))
connection.setRequestProperty("Content-Language", "en-US")
connection.useCaches = false
connection.doOutput = true
//Send request
val wr = DataOutputStream(
connection.outputStream)
wr.writeBytes(encodedFile)
wr.close()
// Get Response
val stream = connection.inputStream
val reader = BufferedReader(InputStreamReader(stream))
var line: String?
while (reader.readLine().also { line = it } != null) {
println(line)
}
reader.close()
} catch (e: Exception) {
e.printStackTrace()
} finally {
connection?.disconnect()
}
}
main()

Adding an Image Hosted Elsewhere via URL:

import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLEncoder
import java.nio.charset.StandardCharsets
fun main() {
val imageURL = "https://i.imgur.com/PEEvqPN.png" // Replace Image URL
val API_KEY = "" // Your API Key
val DATASET_NAME = "your-dataset" // Set Dataset Name (Found in Dataset URL)
// Upload URL
val uploadURL = ("https://api.roboflow.com/dataset/" + DATASET_NAME + "/upload" + "?api_key=" + API_KEY
+ "&name=YOUR_IMAGE.jpg" + "&split=train" + "&image="
+ URLEncoder.encode(imageURL, "utf-8"))
// Http Request
var connection: HttpURLConnection? = null
try {
// Configure connection to URL
val url = URL(uploadURL)
connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
connection.setRequestProperty("Content-Length", Integer.toString(uploadURL.toByteArray().size))
connection.setRequestProperty("Content-Language", "en-US")
connection.useCaches = false
connection.doOutput = true
// Send request
val wr = DataOutputStream(connection.outputStream)
wr.writeBytes(uploadURL)
wr.close()
// Get Response
val stream = connection.inputStream
val reader = BufferedReader(InputStreamReader(stream))
var line: String?
while (reader.readLine().also { line = it } != null) {
println(line)
}
reader.close()
} catch (e: Exception) {
e.printStackTrace()
} finally {
connection?.disconnect()
}
}
main()

Android (Java)

Uploading with base64 encoded image:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class UploadLocal {
public static void main(String[] args) throws IOException {
// Get Image Path
String filePath = System.getProperty("user.dir") + System.getProperty("file.separator") + "YOUR_IMAGE.jpg";
File file = new File(filePath);
// Base 64 Encode
String encodedFile;
FileInputStream fileInputStreamReader = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
fileInputStreamReader.read(bytes);
encodedFile = new String(Base64.getEncoder().encode(bytes), StandardCharsets.US_ASCII);
String API_KEY = ""; // Your API Key
String DATASET_NAME = "your-dataset"; // Set Dataset Name (Found in Dataset URL)
// Construct the URL
String uploadURL =
"https://api.roboflow.com/dataset/"+
DATASET_NAME + "/upload" +
"?api_key=" + API_KEY +
"&name=YOUR_IMAGE.jpg" +
"&split=train";
// Http Request
HttpURLConnection connection = null;
try {
//Configure connection to URL
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",
Integer.toString(encodedFile.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.writeBytes(encodedFile);
wr.close();
// Get Response
InputStream stream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}

Adding an Image Hosted Elsewhere via URL:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class UploadHosted {
public static void main(String[] args) {
String imageURL = "https://i.imgur.com/PEEvqPN.png"; // Replace Image URL
String API_KEY = ""; // Your API Key
String DATASET_NAME = "your-dataset"; // Set Dataset Name (Found in Dataset URL)
// Upload URL
String uploadURL = "https://api.roboflow.com/dataset/" + DATASET_NAME + "/upload" + "?api_key=" + API_KEY
+ "&name=YOUR_IMAGE.jpg" + "&split=train" + "&image="
+ URLEncoder.encode(imageURL, StandardCharsets.UTF_8);
// Http Request
HttpURLConnection connection = null;
try {
// Configure connection to URL
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", Integer.toString(uploadURL.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(uploadURL);
wr.close();
// Get Response
InputStream stream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}

Ruby

Gemfile
source "https://rubygems.org"
gem "httparty", "~> 0.18.1"
gem "base64", "~> 0.1.0"
gem "cgi", "~> 0.2.1"
Gemfile.lock
GEM
remote: https://rubygems.org/
specs:
base64 (0.1.0)
cgi (0.2.1)
httparty (0.18.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0225)
multi_xml (0.6.0)
PLATFORMS
x64-mingw32
x86_64-linux
DEPENDENCIES
base64 (~> 0.1.0)
cgi (~> 0.2.1)
httparty (~> 0.18.1)
BUNDLED WITH
2.2.15

Uploading with base64 encoded image:

require 'base64'
require 'httparty'
encoded = Base64.encode64(File.open("YOUR_IMAGE.jpg", "rb").read)
dataset_name = "your-dataset" # Set Dataset Name (Found in Dataset URL)
api_key = "" # Your API KEY Here
params = "?api_key=" + api_key +
"&name=YOUR_IMAGE.jpg" +
"&split=train"
response = HTTParty.post(
"https://api.roboflow.com/dataset/" + dataset_name + "/upload" + params,
body: encoded,
headers: {
'Content-Type' => 'application/x-www-form-urlencoded',
'charset' => 'utf-8'
})
puts response

Adding an Image Hosted Elsewhere via URL:

require 'httparty'
require 'cgi'
dataset_name = "your-dataset" # Set Dataset Name (Found in Dataset URL)
api_key = "" # Your API KEY Here
img_url = "https://i.imgur.com/PEEvqPN.png" # Construct the URL
img_url = CGI::escape(img_url)
params = "?api_key=" + api_key +
"&name=YOUR_IMAGE.jpg" +
"&split=train" +
"&image=" + img_url
response = HTTParty.post(
"https://api.roboflow.com/dataset/" + dataset_name + "/upload" + params,
headers: {
'Content-Type' => 'application/x-www-form-urlencoded',
'charset' => 'utf-8'
})
puts response

PHP

Uploading with base64 encoded image:

<?php
// Base 64 Encode Image
$data = base64_encode(file_get_contents("YOUR_IMAGE.jpg"));
$api_key = ""; // Set API Key
$dataset_name = "your-dataset"; // Set Dataset Name (Found in Dataset URL)
// URL for Http Request
$url = "https://api.roboflow.com/dataset/"
. $dataset_name . "/upload"
. "?api_key=" . $api_key
. "&name=YOUR_IMAGE.jpg"
. "&split=train";
// Setup + Send Http request
$options = array(
'http' => array (
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => $data
));
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
echo $result;
?>

Adding an Image Hosted Elsewhere via URL:

<?php
$api_key = ""; // Set API Key
$dataset_name = "your-dataset"; // Set Dataset Name (Found in Dataset URL)
$img_url = "https://i.imgur.com/PEEvqPN.png";
// URL for Http Request
$url = "https://api.roboflow.com/dataset/"
. $dataset_name . "/upload"
. "?api_key=" . $api_key
. "&name=YOUR_IMAGE.jpg"
. "&split=train"
. "&image=" . urlencode($img_url);
// Setup + Send Http request
$options = array(
'http' => array (
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST'
));
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
echo $result;
?>

Go

Uploading with base64 encoded image:

package main
import (
"bufio"
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"net/http"
"strings"
)
func main() {
api_key := "" // Your API Key
dataset_name := "Your-Dataset" // Set Dataset Name (Found in Dataset URL)
// Open file on disk.
f, _ := os.Open("YOUR_IMAGE.jpg")
// Read entire JPG into byte slice.
reader := bufio.NewReader(f)
content, _ := ioutil.ReadAll(reader)
// Encode as base64.
data := base64.StdEncoding.EncodeToString(content)
uploadURL := "https://api.roboflow.com/dataset/"+ dataset_name + "/upload"+
"?api_key=" + api_key +
"&name=YOUR_IMAGE.jpg" +
"&split=train"
res, _ := http.Post(uploadURL, "application/x-www-form-urlencoded", strings.NewReader(data))
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}

Adding an Image Hosted Elsewhere via URL:

package main
import (
"fmt"
"net/http"
"net/url"
"io/ioutil"
)
func main() {
api_key := "" // Your API Key
dataset_name := "Your-Dataset" // Set Dataset Name (Found in Dataset URL)
img_url := "https://i.imgur.com/PEEvqPN.png"
uploadURL := "https://api.roboflow.com/dataset/"+ dataset_name + "/upload"+
"?api_key=" + api_key +
"&name=YOUR_IMAGE.jpg" +
"&split=train" + "&image=" + url.QueryEscape(img_url)
res, _ := http.Post(uploadURL, "application/x-www-form-urlencoded", nil)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}

.NET

Uploading with base64 encoded image:

using System;
using System.IO;
using System.Net;
using System.Text;
namespace UploadLocal
{
class UploadLocal
{
static void Main(string[] args)
{
byte[] imageArray = System.IO.File.ReadAllBytes(@"YOUR_IMAGE.jpg");
string encoded = Convert.ToBase64String(imageArray);
byte[] data = Encoding.ASCII.GetBytes(encoded);
string API_KEY = ""; // Your API Key
string DATASET_NAME = "your-dataset"; // Set Dataset Name (Found in Dataset URL)
// Construct the URL
string uploadURL =
"https://api.roboflow.com/dataset/" +
DATASET_NAME + "/upload" +
"?api_key=" + API_KEY +
"&name=YOUR_IMAGE.jpg" +
"&split=train";
// Service Request Config
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Configure Request
WebRequest request = WebRequest.Create(uploadURL);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
// Write Data
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
// Get Response
string responseContent = null;
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader sr99 = new StreamReader(stream))
{
responseContent = sr99.ReadToEnd();
}
}
}
Console.WriteLine(responseContent);
}
}
}

Adding an Image Hosted Elsewhere via URL:

using System;
using System.IO;
using System.Net;
using System.Web;
namespace UploadHosted
{
class UploadHosted
{
static void Main(string[] args)
{
string API_KEY = ""; // Your API Key
string DATASET_NAME = "your-dataset"; // Set Dataset Name (Found in Dataset URL)
string imageURL = "https://i.imgur.com/PEEvqPN.png";
imageURL = HttpUtility.UrlEncode(imageURL);
// Construct the URL
string uploadURL =
"https://api.roboflow.com/dataset/" +
DATASET_NAME + "/upload" +
"?api_key=" + API_KEY +
"&name=YOUR_IMAGE.jpg" +
"&split=train" +
"&image=" + imageURL;
// Service Point Config
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Configure Http Request
WebRequest request = WebRequest.Create(uploadURL);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = 0;
// Get Response
string responseContent = null;
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader sr99 = new StreamReader(stream))
{
responseContent = sr99.ReadToEnd();
}
}
}
Console.WriteLine(responseContent);
}
}
}
We are adding code snippets as they are requested by users. If you'd like to integrate the upload API into your Elixir app, please click here to record your upvote.
In case your data lives in a private bucket, you can use signed URLs to upload via the Roboflow API, as demonstrated here.

Finding Uploaded Images

Images uploaded via the API can be found in the Annotate tab, under the unassigned column and marked as uploaded via API.

Video Upload via API

Looking to upload a video via API? Check out the Video tab in Adding Data for more details.

Upload Annotations via API

If you have an existing annotation workflow in place or want to pre-annotate images with predictions from an external model you can do so via the API.

Upload API Parameters (Annotations)

post
https://api.roboflow.com
/dataset/:url/annotate/:image
Add Annotation
cURL
Python
Javascript
iOS
Android
Ruby
PHP
Go
.NET
Elixir

Linux or macOS

Attaching a VOC XML annotation to an image with ID abc123 in the your-dataset dataset called YOUR_ANNOTATION.xml:
cat YOUR_ANNOTATION.xml | curl -d @- \
"https://api.roboflow.com/dataset/your-dataset/annotate/abc123?\
api_key=YOUR_KEY&\
name=YOUR_ANNOTATION.xml"

Windows

You will need to install curl for Windows. The easiest way to do this is to use the git for Windows installer which also includes the curl command line tool when you select "Use Git and optional Unix tools from the Command Prompt" during installation.
Then you can use the same command as above.

Uploading a Local Annotation

To install dependencies, pip install requests
import requests
annotation_filename = "YOUR_ANNOTATION.xml"
# Read Annotation as String
annotation_str = open(annotation_filename, "r").read()
# Construct the URL
upload_url = "".join([
"https://api.roboflow.com/dataset/your-dataset/annotate/abc123",
"?api_key=YOUR_KEY",
"&name=", annotation_filename
])
# POST to the API
r = requests.post(upload_url, data=annotation_str, headers={
"Content-Type": "text/plain"
})
# Output result
print(r.json())

How To Upload an Annotation with the API (Python)

We also have a video demonstration of using the Upload API with Python: