Pixian API

The Pixian.AI API is currently in beta.
Get API Key

Quickstart

POST a bitmap image and get a background-removed result back:

$ curl https://api.pixian.ai/api/v1/remove-background \
 -u xyz123:[secret] \
 -F 'image=@example.jpeg' \
 -o pixian_result.png
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent

Request request = Request.post("https://api.pixian.ai/api/v1/remove-background")
   .addHeader("Authorization", "Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd")
   .body(
      MultipartEntityBuilder.create()
         .addBinaryBody("image", new File("example.jpeg")) // TODO: Replace with your image
         // TODO: Add more upload parameters here
         .build()
      );
ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse();

if (response.getCode() == 200) {
   // Write result to disk, TODO: or wherever you'd like
   try (FileOutputStream out = new FileOutputStream("pixian_result.png")) {
      response.getEntity().writeTo(out);
   }
} else {
   System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase());
}
using (var client = new HttpClient())
using (var form = new MultipartFormDataContent())
{
   client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "INSERT_API_KEY_HERE");
   form.Add(new ByteArrayContent(File.ReadAllBytes("example.jpeg")), "image", "example.jpeg"); // TODO: Replace with your image
   // TODO: Add more upload parameters here

   var response = client.PostAsync("https://api.pixian.ai/api/v1/remove-background", form).Result;

   if (response.IsSuccessStatusCode)
   {
      // Write result to disk, TODO: or wherever you'd like
      FileStream outStream = new FileStream("pixian_result.png", FileMode.Create, FileAccess.Write, FileShare.None);
      response.Content.CopyToAsync(outStream).ContinueWith((copyTask) => { outStream.Close(); });
   }
   else
   {
       Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase);
   }
}
// Requires "request" to be installed (see https://www.npmjs.com/package/request)
var request = require('request');
var fs = require('fs');

request.post({
  url: 'https://api.pixian.ai/api/v1/remove-background',
  formData: {
    image: fs.createReadStream('example.jpeg'), // TODO: Replace with your image
    // TODO: Add more upload options here
  },
  auth: {user: 'xyz123', pass: '[secret]'},
  followAllRedirects: true,
  encoding: null
}, function(error, response, body) {
  if (error) {
    console.error('Request failed:', error);
  } else if (!response || response.statusCode != 200) {
    console.error('Error:', response && response.statusCode, body.toString('utf8'));
  } else {
    // Save result
    fs.writeFileSync("pixian_result.png", body);
  }
});
$ch = curl_init('https://api.pixian.ai/api/v1/remove-background');

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
    array('Authorization: Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd'));
curl_setopt($ch, CURLOPT_POSTFIELDS,
    array(
      'image' => curl_file_create('example.jpeg'),
      // TODO: Add more upload options here
    ));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

$data = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) {
  // Save result
  file_put_contents("pixian_result.png", $data);
} else {
  echo "Error: " . $data;
}
curl_close($ch);
# Requires "requests" to be installed (see python-requests.org)
import requests

response = requests.post(
    'https://api.pixian.ai/api/v1/remove-background',
    files={'image': open('example.jpeg', 'rb')},
    data={
        # TODO: Add more upload options here
    },
    headers={
        'Authorization':
        'Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd'
    },
)
if response.status_code == requests.codes.ok:
    # Save result
    with open('pixian_result.png', 'wb') as out:
        out.write(response.content)
else:
    print("Error:", response.status_code, response.text)
# Requires: gem install httpclient
require 'httpclient'

client = HTTPClient.new default_header: {
  "Authorization" => "Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd"
}

response = client.post("https://api.pixian.ai/api/v1/remove-background", {
  "image" => File.open("example.jpeg", "rb"), # TODO: Replace with your image
  # TODO: Add more upload parameters here
})

if response.status == 200 then
  # Write result to disk, TODO: or wherever you'd like
  File.open("pixian_result.png", 'w') { |file| file.write(response.body) }
else
  puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason
end
$ curl https://api.pixian.ai/api/v1/remove-background \
 -u xyz123:[secret] \
 -F 'image.url=https://example.com/example.jpeg' \
 -o pixian_result.png
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent

Request request = Request.post("https://api.pixian.ai/api/v1/remove-background")
   .addHeader("Authorization", "Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd")
   .body(
      MultipartEntityBuilder.create()
         .addTextBody("image.url", "https://example.com/example.jpeg") // TODO: Replace with your image URL
         // TODO: Add more upload parameters here
         .build()
      );
ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse();

if (response.getCode() == 200) {
   // Write result to disk, TODO: or wherever you'd like
   try (FileOutputStream out = new FileOutputStream("pixian_result.png")) {
      response.getEntity().writeTo(out);
   }
} else {
   System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase());
}
using (var client = new HttpClient())
using (var form = new MultipartFormDataContent())
{
   client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "INSERT_API_KEY_HERE");
   form.Add(new StringContent("https://example.com/example.jpeg"), "image.url"); // TODO: Replace with your image URL
   // TODO: Add more upload parameters here

   var response = client.PostAsync("https://api.pixian.ai/api/v1/remove-background", form).Result;

   if (response.IsSuccessStatusCode)
   {
      // Write result to disk, TODO: or wherever you'd like
      FileStream outStream = new FileStream("pixian_result.png", FileMode.Create, FileAccess.Write, FileShare.None);
      response.Content.CopyToAsync(outStream).ContinueWith((copyTask) => { outStream.Close(); });
   }
   else
   {
       Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase);
   }
}
// Requires "request" to be installed (see https://www.npmjs.com/package/request)
var request = require('request');
var fs = require('fs');

request.post({
  url: 'https://api.pixian.ai/api/v1/remove-background',
  formData: {
    'image.url': 'https://example.com/example.jpeg', // TODO: Replace with your image
    // TODO: Add more upload options here
  },
  auth: {user: 'xyz123', pass: '[secret]'},
  followAllRedirects: true,
  encoding: null
}, function(error, response, body) {
  if (error) {
    console.error('Request failed:', error);
  } else if (!response || response.statusCode != 200) {
    console.error('Error:', response && response.statusCode, body.toString('utf8'));
  } else {
    // Save result
    fs.writeFileSync("pixian_result.png", body);
  }
});
$ch = curl_init('https://api.pixian.ai/api/v1/remove-background');

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
    array('Authorization: Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd'));
curl_setopt($ch, CURLOPT_POSTFIELDS,
    array(
      'image.url' => 'https://example.com/example.jpeg',
      // TODO: Add more upload options here
    ));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

$data = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) {
  // Save result
  file_put_contents("pixian_result.png", $data);
} else {
  echo "Error: " . $data;
}
curl_close($ch);
# Requires "requests" to be installed (see python-requests.org)
import requests

response = requests.post(
    'https://api.pixian.ai/api/v1/remove-background',
    data={
        'image.url': 'https://example.com/example.jpeg',
        # TODO: Add more upload options here
    },
    headers={
        'Authorization':
        'Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd'
    },
)
if response.status_code == requests.codes.ok:
    # Save result
    with open('pixian_result.png', 'wb') as out:
        out.write(response.content)
else:
    print("Error:", response.status_code, response.text)
# Requires: gem install httpclient
require 'httpclient'

client = HTTPClient.new default_header: {
  "Authorization" => "Basic cHh4YmJ6Yjk2bjJ3OGFtOltzZWNyZXRd"
}

response = client.post("https://api.pixian.ai/api/v1/remove-background", {
  "image.url" => "https://example.com/example.jpeg", # TODO: Replace with your image URL
  # TODO: Add more upload parameters here
})

if response.status == 200 then
  # Write result to disk, TODO: or wherever you'd like
  File.open("pixian_result.png", 'w') { |file| file.write(response.body) }
else
  puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason
end

Migrating from another provider? Check out our migration guide

Authentication & Security

The API uses standard HTTP basic access authentication. All requests to the API must be made over HTTPS and include your API Credentials, with the API Id as the user and API Secret as the password.

Your http client library must support Server Name Indication (SNI) to successfully make requests. If you're getting weird handshake errors, this is most likely it.

Rate Limiting

Usage of the API is rate limited with generous allowances and no hard upper bound.

During normal end-user-driven operation you are unlikely to run into any rate limiting as usage then tends to ebb and flow in a way that the service handles gracefully.

However, for batch jobs we recommend starting out with at most 5 threads, adding 1 new thread every 5 minutes until you have reached the desired level of parallelism. Please reach out before starting if you need more than 100 concurrent threads.

If you submit too many requests you will start getting 429 Too Many Requests responses. When this happens you should apply linear back off: on the first such response, wait 5 seconds until submitting the next request. On the second consecutive 429 response, wait 2*5=10 seconds until submitting the next request. On the third wait 3*5=15 seconds, etc.

You can reset the back off counter after a successful request, and you should apply the back off on a per-thread basis (i.e. the threads should operate independently of each other).

Delta PNG Format Lower Latency & Bandwidth

Pixian.AI is proud to be the first background removal service to offer the Delta PNG output format. Delta PNGs are faster to encode and much smaller than regular PNGs. This makes them highly suitable for latency and bandwidth sensitive applications, like mobile apps.

Learn more Right arrow

Remove Background POST
https://api.pixian.ai/api/v1/remove-background

To remove the background from an image, you do a standard HTTP POST file upload. Keep in mind that the Content-Type has to be multipart/form-data when uploading binary files.

Parameters

The input image must be provided as one of:


Binary

A binary file.


String

A base64-encoded string. The string can be at most 1 megabyte in size.


String

A URL to fetch and process.

Must be a .bmp, .gif, .jpeg, .png, or .tiff file.

The maximum image upload size (= width × height) is 32,000,000 pixels, which gets shrunk to maxPixels.


Integer, 100 to 25000000, default: 25000000

The maximum input image size (= width × height). Images larger than this will be shrunk to this size before processing.


Format: '#RRGGBB', e.g. #0055FF

Background color to apply to the result. Omit to leave a transparent background.

Be sure to include the '#' prefix.


Boolean, default: false

Whether to crop the result to the foreground object.

Very useful together with result.margin and result.targetSize to get a nicely sized and centered result every time.


Format: '(x.y%|px){1,4}', e.g. 10px 20% 5px 15%, default: 0px

Margin to add to the result.

It's added regardless of if the result is cropped to the foreground or not.

If result.targetSize is specified, then the margin is inset, i.e. it doesn't expand the effective target size.

The supported units are % and px. It follows CSS semantics, so you can use any of:

  • [all]
  • [top/bottom] [left/right]
  • [top] [left/right] [bottom]
  • [top] [right] [bottom] [left]


Format: 'w h', e.g. 1920 1080

Enforce a specific result size. The result will be scaled to fit within the specified size. If there's excess space then it's always horizontally centered, with result.verticalAlignment controlling the vertical treatment.


Enum, default: middle

Specifies how to allocate excess vertical space when result.targetSize is used.


Enum, default: auto

Output format. auto is interpreted as png for transparent results, and jpeg for opaque results, i.e. when a background.color has been specified.

deltaPng is an advanced, fast, and highly compact format especially useful for low-latency, bandwidth-constrained situations like mobile apps. It encodes the background as transparent black 0x00000000 and the foreground as transparent white 0x00FFFFFF. Partially transparent pixels have their actual color values. Together with the input image you can use this to reconstruct the full result. Learn more about the Delta PNG format

background.color, result.cropToForeground, result.margin, result.targetSize, and result.verticalAlignment are ignored when using deltaPng. The result must be the same size as the input image, otherwise your decoding will fail, so maxPixels must not have caused the input to be shrunk.


Integer, 1 to 100, default: 75

The quality to use when encoding JPEG results.

Result Headers

X-Credits-Charged Currently returning 0.0. Will return the actual credits charged when we leave beta.
X-Input-Orientation The EXIF orientation tag we read from and applied to the input image. It's an integer value from 1 to 8, inclusive. This is useful if your image loading library doesn't support EXIF orientation. Read more about EXIF orientation here
X-Input-Size [width] [height] of the input image in pixels, before any size constraints were applied.
X-Result-Size [width] [height] of the result image, in pixels.
X-Input-Foreground [top] [left] [width] [height] bounding box of the foreground in the input image coordinates.
X-Result-Foreground [top] [left] [width] [height] bounding box of the foreground in the result image coordinates.
Get API Key