Vectorizer API

The Vectorizer.AI API is currently in beta.
Please create an account and send an email to api.beta@vectorizer.ai to apply.

Quickstart

POST a bitmap image and get a vectorized result back:

$ curl https://vectorizer.ai/api/v1/vectorize \
 -u a_xyz123:[secret] \
 -F 'image=@example.jpeg' \
 -o result.svg
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent

Request request = Request.post("https://vectorizer.ai/api/v1/vectorize")
   .addHeader("Authorization", "Basic dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd")
   .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("result.svg")) {
      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", "dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd");
   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://clippingmagic.com/api/v1/images", form).Result;

   if (response.IsSuccessStatusCode)
   {
      // Write result to disk, TODO: or wherever you'd like
      FileStream outStream = new FileStream("result.svg", 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://vectorizer.ai/api/v1/vectorize',
  formData: {
    image: fs.createReadStream('example.jpeg'), // TODO: Replace with your image
    // TODO: Add more upload options here
  },
  auth: {user: 'a_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("result.svg", body);
  }
});
$ch = curl_init('https://vectorizer.ai/api/v1/vectorize');

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
    array('Authorization: Basic dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd'));
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("result.svg", $data);
} else {
  echo "Error: " . $data;
}
curl_close($ch);
# Requires "requests" to be installed (see python-requests.org)
import requests

response = requests.post(
    'https://vectorizer.ai/api/v1/vectorize',
    files={'image': open('example.jpeg', 'rb')},
    data={
        # TODO: Add more upload options here
    },
    headers={
        'Authorization':
        'Basic dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd'
    },
)
if response.status_code == requests.codes.ok:
    # Save result
    with open('result.svg', '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 dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd"
}

response = client.post("https://vectorizer.ai/api/v1/vectorize", {
  "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("result.svg", 'w') { |file| file.write(response.body) }
else
  puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason
end
$ curl https://vectorizer.ai/api/v1/vectorize \
 -u a_xyz123:[secret] \
 -F 'image.url=https://example.com/example.jpeg' \
 -o result.svg
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent

Request request = Request.post("https://vectorizer.ai/api/v1/vectorize")
   .addHeader("Authorization", "Basic dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd")
   .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("result.svg")) {
      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", "dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd");
   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://clippingmagic.com/api/v1/images", form).Result;

   if (response.IsSuccessStatusCode)
   {
      // Write result to disk, TODO: or wherever you'd like
      FileStream outStream = new FileStream("result.svg", 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://vectorizer.ai/api/v1/vectorize',
  formData: {
    'image.url': 'https://example.com/example.jpeg', // TODO: Replace with your image
    // TODO: Add more upload options here
  },
  auth: {user: 'a_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("result.svg", body);
  }
});
$ch = curl_init('https://vectorizer.ai/api/v1/vectorize');

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
    array('Authorization: Basic dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd'));
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("result.svg", $data);
} else {
  echo "Error: " . $data;
}
curl_close($ch);
# Requires "requests" to be installed (see python-requests.org)
import requests

response = requests.post(
    'https://vectorizer.ai/api/v1/vectorize',
    data={
        'image.url': 'https://example.com/example.jpeg',
        # TODO: Add more upload options here
    },
    headers={
        'Authorization':
        'Basic dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd'
    },
)
if response.status_code == requests.codes.ok:
    # Save result
    with open('result.svg', '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 dmt5YzY3a3FhMjd5aWRkOltzZWNyZXRd"
}

response = client.post("https://vectorizer.ai/api/v1/vectorize", {
  "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("result.svg", 'w') { |file| file.write(response.body) }
else
  puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason
end

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).

Vectorize POST https://vectorizer.ai/api/v1/vectorize

To vectorize 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 URL to fetch.

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

The maximum image upload size (= width × height) is 33,554,432 pixels, which gets shrunk to 2,097,252 pixels. Please pre-shrink your images to the latter size or smaller before uploading.