HTTP API Overview

To use the API, make an HTTP request with an URL of an image to optimize (you can make the request using PHP, NodeJS or even Bash). The ImageOptim API will download the image, perform its magic, and return an optimized image as a response to the request. Basically, you download a better version of any image from the ImageOptim API. Save the optimized files and serve them from your server.

On this page:

Request URL

Make a POST request (how to) to a URL constructed as follows: URL


— username of your ImageOptim API account. Your API username is lbstqgpwpz. We've updated all code examples to use it.

More about usernames


— a comma-separated list of values and keywords that describe desired image dimensions, quality, etc. (width x height, 2x, full, scale-down, fit, crop, quality, timeout).

This part of the URL is required. In case you don't want to specify any options, and only optimize images without resizing them, use the full option (as in full-size).

List of options

Image URL

— (optional) an absolute URL of the image to optimize, e.g.

If the image isn't available publicly on the Internet, you can upload it directly instead.

For best results, please use JPEG files saved at very high quality (PNG files are good to). ImageOptim will automatically set optimum quality for optimized files if the source images had sufficiently high quality.,crop/ For your account ⤵︎ get the source image from ⤴︎ and crop it to 100px square

Options overview

Multiple options are separated with commas, e.g. 100x100,2x,fit,quality=low. Options can be in any order.


Full image size. No resizing takes place, e.g.

widthxheight Maximum image width and height, e.g.

Dimensions are specified in CSS pixels, but without the px suffix. Images are always resized preserving aspect ratio.

width Maximum image width. The height will vary depending on image's aspect ratio, e.g.

Exact interpretation of dimensions depends on the following options:

1x, 2x or 3x default 1x

Multiply image dimensions by 2 or 3 for High-DPI ("Retina") displays. This is for use with HTML5's srcset attribute that defines higher-resolution image alternatives.

By default resizing to 160x100 will create an image that is up to 160x100 pixels large, but:,2x/

resizing to 160x100,2x will create an image that is up to 320x200 pixels large (in "device" pixels), and is optimized for display at size of 160x100 CSS px on double-density displays.


Image is resized to completely fit within the given dimensions without cropping. Aspect ratio is preserved, so one of the dimensions may be smaller than the specified maximum. Small images will be enlarged if necessary.,fit/

500x500,fit would resize a 1000x200 image to 500x100, and a 16x16 image would be (wastefully) enlarged to 500x500.

scale-down the default

Like fit, but the image is never enlarged. Image size is always equal or smaller than the given dimenions.

This is the default method, so you don't need to specify it explicitly:,scale-down/ is same as

500x500,scale-down would resize a 1000x200 image to 500x100, but a 16x16 image would stay 16x16.


Image is scaled and cropped to completely fill the given width and height, so that the resulting image always has exactly the dimensions specified, e.g.,crop/


Same as crop, but instead of cropping towards image center, automatically selects the most important aera of the image.,crop=auto/


You can select which side of the image should be kept when cropping by adding an argument with one of top, left, right, bottom.

For example, this always keeps the top of the image, and the bottom will be cut off if necessary:,crop=top/


You can select focal point for cropping. The image will be cropped so that the given point always remains in the image. The point's coordinates are specified within uncropped image, but the position is expressed using fractional numbers between 0 to 1, e.g. 0 is top/left, 0.5 is center, 1 is bottom/right. These numbers are x pixel position divided by width and y pixel position divided by height. This way the focal point can be specified independently of image's actual size.

For example, crop focusing on a point that is in left third of the image, about 20% from the top of the image:,crop=0.333x0.2/


Removes solid-color border from the image. Only trims pixels that have exactly the same color, so it will remove borders added through image processing, but it's unlikely to remove edges of natual photos. Trimming is before any other resizing or cropping.

bgcolor=RGB default bgcolor=FFF RGB color as 3 or 6 hex digits, e.g. FFAAF8 (without #), to use as a background color when adding padding to the image.
quality=preset default quality=medium

Specifies desired image quality when saving images in a lossy format. It's a trade-off: higher quality images cost more bandwidth and download slowly. Lower quality images are faster and take less disk space. ImageOptim works hard to give you the best of both.

⚠️ JPEG files can only have their quality decreased. If the input image is a low-quality JPEG, the output will not look any better. For best results, save original images as lossless PNG or JPEG at maximum quality, so that the ImageOptim API has the perfect source image to work with, and can produce images at optimum quality.

The quality presets are:

  • quality=low — offers smallest possible file size, but compression artefacts will be noticeable. Low quality setting is recommended for images that may be large, but are not critical for the site, e.g. backgrounds, splash screens.

  • quality=medium — balanced quality/filesize tradeoff giving small file sizes and barely noticeable lossy compression in normal viewing conditions. This is the default setting.

  • quality=high — avoids visible compression artefacts at the cost of higher (sometimes much higher) file size. This setting may be necessary for images that will be enlarged, sharpened or have contrast increased on the client-side (e.g. when used as a texture in a game).

  • quality=lossless — the optimization does not change a single pixel (this option is respected only if the image is not resized). Lossless-only optimization should be reserved only for special cases, e.g. images that are used as “originals” for print or further editing, such as logos in a press kit. It's not recommended for regular images displayed on a website, because lossless compression produces files many times larger than even the high quality lossy setting.


By default the best file format is chosen automatically. You can request images converted to a specific format: png, jpeg, webm or h264.

The format=webm/format=h264 settings are for converting animated GIFs to video.

timeout=seconds default timeout=30

Maximum time allowed to spend on optimization. In seconds, and decimal point is allowed. The default is 30 seconds.

This setting is for servers that can't wait too long for results, e.g. when calling the API from PHP which limits maximum execution time.

Good optimizations are slow, especially when images are large, so the longer the timeout the better. Be careful: if ImageOptim doesn't have enough time to finish optimization, it will return less optimized image, or even redirect to the source image as a fallback.

Making the request

You should keep (cache) the optimized files. Use the API to process the images once (e.g. when they're uploaded) and then serve them from your server. This will give you best performance and maximum control over how files are handled.


It's possible to use the API without any special libraries. curl is useful for trying things out.

curl -XPOST -O -L ''
  • -XPOST makes a POST request rather than GET (that's a requirement of the API).
  • -L enables following HTTP redirects, which are required by the API.
  • -O saves output to a file. Without it curl would print tons of gibberish image data to your terminal. You can also use -o 'filename' to save image under a specific filename.

If you replace -O with -I you'll see HTTP headers instead — very useful for debugging!

Other useful flags you can add are --fail to handle errors in Bash, --silent to hide progress messages.

With Wget
wget --method=POST ''
  • --method=POST makes a POST request rather than GET (that's a requirement of the API).
  • -O 'filename' can be used to save optimized image under a specific filename.

With PHP

We have a library for PHP. Or you can call the API with vanilla PHP:


// Full-size master image URL
$sourceImageUrl = '';

// Comma-separated options string
$options = 'full';

// Settings needed to switch to the POST method
$postContext = stream_context_create([
    'http' => [
        'method' => 'POST',

// Get image data from the API
$imageData = file_get_contents(
    '' . $options . '/' . $sourceImageUrl,
    false, $postContext);

// At this point $imageData contains resized/optimized image
// You can save it to the disk on the server
file_put_contents('images/image-optimized.png', $imageData);

With NodeJS

You can use your favourite HTTP library (Node's built-in https module works too). We're using superagent module for the example:

npm install --save superagent
var superagent = require('superagent');
var fs = require('fs');

// Full-size master image URL
var sourceImageURL = '';

// Comma-separated options string
var options = 'full';

// Get image data from the API'' + options + '/' + sourceImageURL)
    .end(function(err, res) {
        var imageData = res.body;

        // At this point imageData contains resized/optimized image
        // You can save it to the disk on the server
        fs.writeFileSync('images/image-optimized.png', imageData);

HTTP Response


If everything goes well, you'll either get a:

  • response status 303 — a redirect to a URL to GET the optimized image from. Most HTTP libraries follow redirects automatically, so your code won't need to handle that explicitly.
  • response status 200 — all OK, and the raw image file will be sent in the response body.

The image will be sent as binary data, with Content-Type: image/jpeg or image/png, etc. There's no extra ceremony, no JSON anywhere. Just the image file.


In cases where options set were not quite right, but close enough to work, ImageOptim API will generate an optimized image as best as it can, but additionally it'll set a Warning HTTP header with a message detailing what was wrong. We recommend that you log any Warning headers found in responses and review them.


On error you'll get a response with status in 4xx or 5xx range, and a human-readable error description in the body.

You can open the URL you're requesting in a web browser to get specific information about the error.

  • Response status 403 — if the username is missing or incorrect.
    • They're case-sensitive.
    • Watch out for superfluous slashes in the URL.
  • Response status 400 — if the options or image URL are missing or incorrect.
    • The options part of the URL is required.
    • Options are comma-separated, without spaces.
    • If some options are wrong, the body of the response will contain more information.
  • Response status 404 — we couldn't find the image you requested.
    • Is the image on public Internet? We can't fetch images from localhost. Use uploads instead.
    • Is the URL to the image absolute (with protocol and domain name)?
    • If you're including filenames in the URL that contain spaces or non-ASCII characters, you will need to URL-encode the filenames.
  • Response status 402 — payment required.


ImageOptim API will respect cachability of images if fetches, and pass through equivalent Cache-Control headers.


You have a free trial. See pricing.

Maximum image size is 10000x10000 pixels (100 megapixels). Maximum file size is 50MB. There's no hard limit on number of concurrent requests to the API (4-16 is reasonable).

Supported formats are JPEG, PNG and non-animated GIF. There is partial support for animated GIF and SVG.


  • Allow redirects! The API will use redirects to avoid timeouts and improve caching. Use curl -L in Bash. Other tools and libraries usually follow redirects by default.

  • Set long request timeout. Good optimization takes time, especially if you're working with high-resolution images. We recommend at least 30-second timeout. If you're in a hurry and can't wait that long, add a timeout option to the request, and ImageOptim API will try to finish within the time given.

If you have problems with special characters, such as commas, colons or spaces in filenames, use URL-encoding.

If anything is wrong or missing, feel free to ask questions or leave feedback.