Compress API Reference

The API is hosted at  optimize.exactlywww.com and may be accessed by either HTTPS or HTTP (HTTPS is preferred). This document describes how to interact with the API directly, and will give examples with the curl utility. All requests to the API must use the POST method and include a user-agent.

To access the API using PHP, please use our PHP library. If you have implemented access to the API in another programming language, I would be happy to feature your code examples/libraries here for others to use.

Authentication – /verify/

To use the API, you must provide a valid API key. You can get an API key if you do not already have one.

All data sent to the API must be sent via POST variables, and the API key is transmitted as  api_key. The simplest request that can be used for testing is to POST your key to https://optimize.exactlywww.com/verify/

There are three possible responses (all are JSON encoded, but you can just check the response for the presence of these values):

  • “great” = verification successful
  • “exceeded” = indicates a valid key with no remaining image credits. This can be useful to stop optimization attempts when doing batch operations.
  • “invalid” = indicates that the key is not valid (not found)

It is not required to send a request to /verify/ for each image, as the optimization endpoint will authenticate all API keys. However, it IS recommended to periodically test an API key to make sure it is still valid so that your program is not sending unnecessary optimization requests. Thus we recommend caching the status every 24 hours, but only while optimizations are being attempted.

Try it out with curl (the key ‘abc123’ will always return ‘great’):

curl --data api_key=abc123 https://optimize.exactlywww.com/verify/

Usage – /quota/v2/

If you are developing software that will be used by many people (or at least you hope so), it is useful to display the number of credits available. This can be done by sending a request nearly identical to the authentication request. The only difference is that you send it to https://optimize.exactlywww.com/quota/v2/

For valid API keys, the response is JSON-encoded with the following data (invalid keys will receive an empty response):

  • licensed – The number of images allowed per month. A value of 0 indicates the user is on a metered or unlimited plan OR that the user does not have a monthly plan and has pre-paid for a certain number of credits instead.
  • consumed – The number of images optimized in this billing cycle. A negative value indicates how many credits are remaining when using pre-paid options, whereas a positive value will indicate how many images they have optimized on their monthly subscription.
  • days – The number of days until the next renewal, IF they have a subscription.
  • version – an internal ID that is used to calculate the billing rate. The current default is 3.
  • metered – the account has a “pay as you go” subscription
  • unlimited – the account has an unlimited subscription
  • recharge – the account is using pre-paid credits with auto-refill enabled
  • excredits – the number of credits licensed each month for an Easy IO/ExactDN Developer subscription (this is now obsolete with the new unlimited plans)
  • amount_due – the current balance for a metered subscription
  • status – will be either ‘active’ or 'expired'

You can try this with curl (the key ‘abc123’ will return an auto-generated response):

curl --data api_key=abc123 https://optimize.exactlywww.com/quota/v2/

Optimization – /v2/

There are only two required pieces of information to optimize an image:  api_key and a file to optimize. As before, this information must be sent in a POST request. The API returns the optimized image directly as the response body, where an empty (zero-byte) response indicates no additional savings were possible. These requests should be sent to https://optimize.exactlywww.com/v2/

The basic example with curl, assuming there is a file named ‘image_to_optimize.jpg’ in the current directory, would be as follows:

curl --form api_key=abc123 --form file=@image_to_optimize.jpg https://optimize.exactlywww.com/v2/ > optimized_image.jpg

The file type of the optimized file should be checked to ensure that a valid image was returned before replacing the original image with the optimized one, since an empty response is used to indicate no additional savings was achieved (or you could just check for an empty file).

Additional request options

There are several other options available to preserve metadata, like EXIF and copyright info, as well options for lossy compression, webp image generation, and image conversion:

  • filename: The API logs all images optimized so that API users may view their history at any time independently of whatever plugin or platform they are using. This allows a developer to log the full file-system path for better diagnostics and debugging. If a filename parameter is not provided, the API will simply log the name of the file parameter, like ‘image_to_optimize.jpg’ instead of something more exact like ‘/var/www/html/images/image_to_optimize.jpg’.
  • metadata: 1 = preserve all metadata possible, 0 = strip all metadata
  • height: Specify a number of pixels to resize the height of a WebP image (webp = 1). Use this to avoid using resized (and compressed) JPG resizes to generate a WebP image that will result in further quality loss.
  • width: Specify a number of pixels to resize the width of a WebP image (webp = 1). Use this to avoid using resized (and compressed) JPG resizes to generate a WebP image that will result in further quality loss.
  • crop: 1 = constrain/crop WebP image (webp = 1) to the exact dimensions specified in width and/or height. 0 = scale the image to the lower of width or height.
  • lossy: 1 enables higher compression with minimal quality loss for JPG, PNG, and PDF files, 0 uses standard lossless compression for zero quality loss.
  • lossy_fast: 1 enables much faster compression, but average savings is 10-20% less than regular lossy mode, 0 uses regular lossy when lossy = 1.
  • convert: 1 enables conversion mode for JPG to PNG, PNG to JPG or GIF to PNG. The API will only convert PNG images that have alpha/transparency if jpg_fill is specified (see below). Animated GIF files will do something unexpected when attempting to convert to PNG, most likely taking just the first frame of the image. Thus it is recommended to check for animated GIF files on the “client” system before attempting to upload to the API.
  • compress: 1 is for default SVG optimizations, 0 for minimal SVG optimization.
  • jpg_fill: This is only used when convert = 1 and must be in HTML hexadecimal notation (#ffffff = white). Only used to set the background/fill color for PNG images that are converted to JPG. Leave empty to skip conversion for transparent PNG images.
  • quality: Used when creating WebP files and when processing PNG images with convert = 1. Accepts a value from 1-100. Default is 82.
  • webp: 1 enables WebP generation, and will always return a WebP file even if it is not smaller than the original. It is up to the client software to determine if it is desirable to keep all WebP images received, or only those smaller than the original. GIF conversion is always lossless for initial release, but a lossy option may be introduced in the future. Note: it is recommended to also compress the original file, since not all browsers will display WebP images.

As a more complete example, here is what it would look like with all options specified:

curl --form filename=/var/www/image_to_optimize.jpg --form convert=0 --form metadata=1 --form api_key=abc123 --form jpg_fill=#ffffff --form quality=92 --form lossy=0 --form lossy_fast=0 --form webp=0 --form file=@image_to_optimize.jpg https://optimize.exactlywww.com/v2/ > optimized_image.jpg

Rotate (auto) – /rotate/

First, an explanation of the purpose of this endpoint. Many devices still make use of the EXIF Orientation flag to indicate the direction the camera was held during the photo. This is all well and good if one never intends to edit a photo or resize it. If you strip the metadata, or create a resized version with WordPress, the Orientation flag becomes useless and your image goes sideways. So, rotation is intended to be used so that an original upload can be rotated before being used to create derivative images. The auto-rotated image is lossless, but is not optimized so that requests to this endpoint are as fast as possible. Metadata will be preserved as much as is possible, and the Orientation flag will be set to 1. The JPG format suffers from one constraint during lossless rotation, such that any image which is not evenly divisible by 16 will have up to 15 pixels trimmed from one edge during rotation. Any image sent to the standard optimization endpoint (above) will be automatically auto-rotated also. So, on to the good stuff…

Similar to optimization, there are only two required pieces of information to auto-rotate an image:  api_key and a file to auto-rotate. As always, this information must be sent in a POST request. Calls to the rotation endpoint are similar to WebP generation. No credits are used, but a valid and active API key is required. The API returns the auto-rotated image directly as the response body, or a JSON-encoded error like so: {“error”:”failed”}

An error message of “failed” means that auto-rotation was not necessary, the Orientation field was absent, or something else prevented the image from being rotated. A message of “exceeded” means the API key provided was invalid. These requests should be sent to https://optimize.exactlywww.com/rotate/

The basic example with curl, with a file named ‘image_to_rotate.jpg’ in the current directory, would be as follows:

curl --form api_key=abc123 --form file=@image_to_rotate.jpg https://optimize.exactlywww.com/rotate/ > rotated_image.jpg

The file type of the optimized file should be checked to ensure that an image was returned before replacing the original image with the rotated one, since a JSON response is used to indicate no rotation was performed.

Resize – /resize/

This endpoint is for GIF images. The PHP libraries used by WordPress for image manipulation (GD, ImageMagick, and GraphicsMagick) do not preserve animation within GIF images. This endpoint uses Gifsicle to ensure that animation is preserved for GIF images during resizing.

The resized image is not optimized so that requests to this endpoint are as fast as possible. 

There are ten required pieces of information to resize an image: an  api_key, a file, and then the coordinates/dimensions for scaling/resizing.

  • dst_x: should be 0, and may become optional in the future.
  • dst_y: same as dst_x, should be 0.
  • dst_w: the desired width.
  • dst_h: the desired height.
  • src_x: the X-coordinate on the original image (from left). Should be 0, unless cropping is desired.
  • src_y: the Y-coordinate on the original image (from top). Again, should be 0 unless cropping is desired.
  • src_w: The width of the original image to use. Should be the same as the actual width unless cropping.
  • src_h: The height of the original image to use. Should be the actual height unless cropping.

As always, this information must be sent in a POST request. Calls to the resizing endpoint use no credits, but a valid and active API key is required. The API returns the resized image directly as the response body, or a JSON-encoded error like so: {“error”:”failed”}

An error message of “failed” means that resizing was not necessary or something else prevented the image from being resized. A message of “exceeded” means the API key provided was invalid. These requests should be sent to https://optimize.exactlywww.com/resize/

An example with curl, with a file named ‘image_to_resize.gif’ in the current directory, would be as follows:

curl --form api_key=abc123 --form dst_y=0 --form dst_x=0 --form dst_w=150 --form height=150 --form src_x=0 --form src_y=77 --form src_w=345 --form src_h=345 --form file=@image_to_resize.gif https://optimize.exactlywww.com/resize/ > resized_image.gif

The file/mime type of the optimized file should be checked to ensure that an image was returned before replacing the original image with the resized one, since a JSON response is used to indicate no resizing was performed.

Have an idea, or need help?

If you have any questions, suggestions, or ideas about the API, feel free to contact us.

Still need help? Contact Us Contact Us