Hosted API (Remote Server)
Leverage your custom trained model for cloud-hosted inference.
Overview
Each model trained with Roboflow Train is deployed as a custom API you can use to make predictions from any device that has an internet connection. Inference is done on the server so you don't need to worry about the edge device's hardware capabilities.
We automatically scale this API up and down and do load balancing for you so that you can rest assured that your application will be able to handle sudden spikes in traffic without having to pay for GPU time you're not using. Our hosted prediction API has been battle-hardened to handle even the most demanding production applications (including concurrently surviving through the famous Hacker News and Reddit "hugs of death" without so much as batting an eye).
A video guide for Utilizing Roboflow's Hosted Inference API

The hosted API inference route returns a JSON object containing an array of predictions. Each prediction has the following properties:
  • x = the horizontal center point of the detected object
  • y = the vertical center point of the detected object
  • width = the width of the bounding box
  • height = the height of the bounding box
  • class = the class label of the detected object
  • confidence = the model's confidence that the detected object has the correct label and position coordinates
You'll notice the "image" under "predictions". This contains the width and height of the image or video frame that was sent to the API for inference.
  • width = the width of the bounding box
  • height = the height of the bounding box
// an example JSON object
{
"predictions": [
{
"x": 189.5,
"y": 100,
"width": 163,
"height": 186,
"class": "helmet",
"confidence": 0.544
}
],
"image":
{"width": 2048,
"height": 1371
}
}
Note: position (0,0) refers to the top-left corner of the image.

The easiest way to familiarize yourself with the inference endpoint is to visit the Example Web App. To use the Web App, simply input your model , version and api_key. These will be pre-filled for you after training completes if you click through via the web UI under your versions "Training Results" section.
Then select an image via Choose File. After you have chosen the settings you want, click Run Inference.
On the left side of the screen, you will see example JavaScript code for posting a base64-encoded image to the inference endpoint. Within the form portion of the Web App, you can experiment with changing different API parameters when posting to the API.
  • Min Confidence - The minimum model confidence required for a model to return a prediction
  • Max Overlap - The maximum overlap for bounding boxes to display. e.g. at 0%, any overlap among two boxes of the same class results in only one box for that class being returned.

To use the inference API, you will need your model url slug, version number and the API key for the workspace the project belongs to. Your API key can be retrieved from in your workspace's settings page under the "Roboflow API" section. Your model url slug is the unique and url-safe version of your dataset name. The easiest way to retrieve it is via the web UI by clicking the "curl command" link:

post
https://detect.roboflow.com
/:datasetSlug/:versionNumber
Using the Inference API

For your convenience, we've provided code snippets for calling this endpoint in various programming languages. If you need help integrating the inference API into your project don't hesitate to reach out.
All examples upload to an example dataset with a model-endpoint of your-dataset-slug/your-version. You can easily find your dataset's identifier by looking at the curl command shown in the Roboflow web interface after your model has finished training.
Note: These docs are autogenerated with your API key and version in your Deploy tab within the Roboflow application
Python
cURL
Javascript
Swift/iOS
Android
Ruby
PHP
Go
.NET
Elixir

To install dependencies, pip install roboflow
from roboflow import Roboflow
rf = Roboflow(api_key="API_KEY")
project = rf.workspace().project("MODEL_ENDPOINT")
model = project.version(VERSION).model
# infer on a local image
print(model.predict("your_image.jpg", confidence=40, overlap=30).json())
# visualize your prediction
# model.predict("your_image.jpg", confidence=40, overlap=30).save("prediction.jpg")
# infer on an image hosted elsewhere
# print(model.predict("URL_OF_YOUR_IMAGE", hosted=True, confidence=40, overlap=30).json())

Retrieving JSON predictions for a local file called YOUR_IMAGE.jpg:
base64 YOUR_IMAGE.jpg | curl -d @- \
"https://detect.roboflow.com/your-model/42?api_key=YOUR_KEY"
Inferring on an image hosted elsewhere on the web via its URL (don't forget to URL encode it):
curl -X POST "https://detect.roboflow.com/your-model/42?\
api_key=YOUR_KEY&\
image=https%3A%2F%2Fi.imgur.com%2FPEEvqPN.png"

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.

We're using axios to perform the POST request in this example so first run npm install axios to install the dependency.

const axios = require("axios");
const fs = require("fs");
const image = fs.readFileSync("YOUR_IMAGE.jpg", {
encoding: "base64"
});
axios({
method: "POST",
url: "https://detect.roboflow.com/your-model/42",
params: {
api_key: "YOUR_KEY"
},
data: image,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error.message);
});

const axios = require("axios");
axios({
method: "POST",
url: "https://detect.roboflow.com/your-model/42",
params: {
api_key: "YOUR_KEY",
image: "https://i.imgur.com/PEEvqPN.png"
}
})
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error.message);
});

We have realtime on-device inference available via roboflow.js; see the documentation here.

import UIKit
// Load Image and Convert to Base64
let image = UIImage(named: "your-image-path") // path to image to upload ex: image.jpg
let imageData = image?.jpegData(compressionQuality: 1)
let fileContent = imageData?.base64EncodedString()
let postData = fileContent!.data(using: .utf8)
// Initialize Inference Server Request with API_KEY, Model, and Model Version
var request = URLRequest(url: URL(string: "https://detect.roboflow.com/your-model/your-model-version?api_key=YOUR_APIKEY&name=YOUR_IMAGE.jpg")!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
// Execute Post Request
URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
// Parse Response to String
guard let data = data else {
print(String(describing: error))
return
}
// Convert Response String to Dictionary
do {
let dict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
// Print String Response
print(String(data: data, encoding: .utf8)!)
}).resume()

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 MODEL_ENDPOINT = "dataset/v" // Set model endpoint (Found in Dataset URL)
// Construct the URL
val uploadURL ="https://detect.roboflow.com/" + MODEL_ENDPOINT + "?api_key=" + API_KEY + "&name=YOUR_IMAGE.jpg";
// 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()

import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLEncoder
fun main() {
val imageURL = "https://i.imgur.com/PEEvqPN.png" // Replace Image URL
val API_KEY = "" // Your API Key
val MODEL_ENDPOINT = "dataset/v" // Set model endpoint
// Upload URL
val uploadURL = "https://detect.roboflow.com/" + MODEL_ENDPOINT + "?api_key=" + API_KEY + "&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 = URL(uploadURL).openStream()
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()

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class InferenceLocal {
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 MODEL_ENDPOINT = "dataset/v"; // model endpoint
// Construct the URL
String uploadURL = "https://detect.roboflow.com/" + MODEL_ENDPOINT + "?api_key=" + API_KEY
+ "&name=YOUR_IMAGE.jpg";
// 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();
}
}
}
}

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 InferenceHosted {
public static void main(String[] args) {
String imageURL = "https://i.imgur.com/PEEvqPN.png"; // Replace Image URL
String API_KEY = ""; // Your API Key
String MODEL_ENDPOINT = "dataset/v"; // model endpoint
// Upload URL
String uploadURL = "https://detect.roboflow.com/" + MODEL_ENDPOINT + "?api_key=" + API_KEY + "&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 = new URL(uploadURL).openStream();
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();
}
}
}
}

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

require 'base64'
require 'httparty'
encoded = Base64.encode64(File.open("YOUR_IMAGE.jpg", "rb").read)
model_endpoint = "dataset/v" # Set model endpoint
api_key = "" # Your API KEY Here
params = "?api_key=" + api_key
+ "&name=YOUR_IMAGE.jpg"
response = HTTParty.post(
"https://detect.roboflow.com/" + model_endpoint + params,
body: encoded,
headers: {
'Content-Type' => 'application/x-www-form-urlencoded',
'charset' => 'utf-8'
})
puts response

require 'httparty'
require 'cgi'
model_endpoint = "dataset/v" # Set model endpoint
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 + "&image=" + img_url
response = HTTParty.post(
"https://detect.roboflow.com/" + model_endpoint + params,
headers: {
'Content-Type' => 'application/x-www-form-urlencoded',
'charset' => 'utf-8'
})
puts response
Inferring on a Local Image
<?php
// Base 64 Encode Image
$data = base64_encode(file_get_contents("YOUR_IMAGE.jpg"));
$api_key = ""; // Set API Key
$model_endpoint = "dataset/v"; // Set model endpoint (Found in Dataset URL)
// URL for Http Request
$url = "https://detect.roboflow.com/" . $model_endpoint
. "?api_key=" . $api_key
. "&name=YOUR_IMAGE.jpg";
// 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;
?>

<?php
$api_key = ""; // Set API Key
$model_endpoint = "dataset/v"; // Set model endpoint (Found in Dataset URL)
$img_url = "https://i.imgur.com/PEEvqPN.png";
// URL for Http Request
$url = "https://detect.roboflow.com/" . $model_endpoint
. "?api_key=" . $api_key
. "&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;
?>
Inferring on a Local Image
package main
import (
"bufio"
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"net/http"
"strings"
)
func main() {
api_key := "" // Your API Key
model_endpoint := "dataset/v" // Set model endpoint
// 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://detect.roboflow.com/" + model_endpoint + "?api_key=" + api_key + "&name=YOUR_IMAGE.jpg"
req, _ := http.NewRequest("POST", uploadURL, strings.NewReader(data))
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
bytes, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(bytes))
}

package main
import (
"fmt"
"net/http"
"net/url"
"io/ioutil"
)
func main() {
api_key := "" // Your API Key
model_endpoint := "dataset/v" // Set model endpoint
img_url := "https://i.ibb.co/jzr27x0/YOUR-IMAGE.jpg"
uploadURL := "https://detect.roboflow.com/" + model_endpoint + "?api_key=" + api_key + "&image=" + url.QueryEscape(img_url)
req, _ := http.NewRequest("POST", uploadURL, nil)
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
bytes, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(bytes))
}
Inferring on a Local Image
using System;
using System.IO;
using System.Net;
using System.Text;
namespace InferenceLocal
{
class InferenceLocal
{
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 MODEL_ENDPOINT = "dataset/v"; // Set model endpoint
// Construct the URL
string uploadURL =
"https://detect.roboflow.com/" + MODEL_ENDPOINT + "?api_key=" + API_KEY
+ "&name=YOUR_IMAGE.jpg";
// 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);
}
}
}

using System;
using System.IO;
using System.Net;
using System.Web;
namespace InferenceHosted
{
class InferenceHosted
{
static void Main(string[] args)
{
string API_KEY = ""; // Your API Key
string imageURL = "https://i.ibb.co/jzr27x0/YOUR-IMAGE.jpg";
string MODEL_ENDPOINT = "dataset/v"; // Set model endpoint
// Construct the URL
string uploadURL =
"https://detect.roboflow.com/" + MODEL_ENDPOINT
+ "?api_key=" + API_KEY
+ "&image=" + HttpUtility.UrlEncode(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 inference API into your Elixir app, please click here to record your upvote.

To get predictions from your model on a video, split it into frames, perform inference on each frame, then composite the predictions back into a rendered video.
We have an open source video inference utility script that performs these steps with ffmpeg and the Roboflow Inference API:
GitHub - roboflow-ai/video-inference: Example showing how to do inference on a video file with Roboflow Infer
GitHub

You can also pipe frames from your webcam to your Roboflow model for predictions. We've created a tutorial with example code to show you how:
Using Your Webcam with Roboflow Models
Roboflow Blog

If you pass format=image in the query string the inference API will return a base64 encoded string of your image with the inference detections drawn on top. You can decode this with your favorite image processing library - here we provide an example with cv2 and numpy
# Get prediction from Roboflow Infer API
resp = requests.post(upload_url, data=img_str, headers={
"Content-Type": "application/x-www-form-urlencoded"
}, stream=True).raw
# Parse result image
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)

Frameworks and packages for rendering bounding boxes can differ in positional formats. Given the response JSON object's properties, a bounding box can always be drawn using some combination of the following rules:
  • the center point will always be (x,y)
  • the corner points (x1, y1) and (x2, y2) can be found using:
    • x1 = x - (width/2)
    • y1 = y - (height/2)
    • x2 = x + (width/2)
    • y2 = y + (height/2)
The corner points approach is a common pattern and seen in libraries such as Pillow when building the box object to render bounding boxes within an Image.
Don't forget to iterate through all detections found when working with predictions!
# example box object from the Pillow library
for bounding_box in detections:
x1 = bounding_box['x'] - bounding_box['width'] / 2
x2 = bounding_box['x'] + bounding_box['width'] / 2
y1 = bounding_box['y'] - bounding_box['height'] / 2
y2 = bounding_box['y'] + bounding_box['height'] / 2
box = (x1, x2, y1, y2)

Note: to receive an image with predicted box output - just pass "format=image" as a query parameter. This section shows an example if you want to double check and parse your JSON output.
Let's suppose you've created an inference url to return JSON predictions like so:
parts = []
url_base = 'https://detect.roboflow.com/'
endpoint = '[YOUR-MODEL]'
access_token = '?access_token=[YOUR_TOKEN]'
format = '&format=json'
confidence = '&confidence=10'
stroke='&stroke=5'
parts.append(url_base)
parts.append(endpoint)
parts.append(access_token)
parts.append(format)
parts.append(confidence)
parts.append(stroke)
url = ''.join(parts)
And you've drawn an inference from your API like so:
import glob