CDN API documentation

CDN or Content Delivery Network is a system of servers deployed in multiple data centers across the world. Such approach provides for faster content delivery. Uploadcare CDN does not simply deliver files, it also provides URL-based API for on-the-fly processing of the uploaded content.

Schemas And Domains

Normally, all requests should be made to domain. Either HTTP or HTTPS protocol can be used.

While on paid plans, you can connect our CDN to a domain or a subdomain of your own. (Let’s Encrypt SSL certificate included). On High volume plans you get an option of using your own CDN on top of our infrastructure.

File API

Please note that all of the file-related URLs should begin with the assigned UUIDs. This link, for instance, returns just the original uploaded file:

You can apply operations (transformations, etc.) by appending them to the URL and using /-/ as a separator. Operations consist of names and arguments, separated by forward slashes (/). Here, take a look at the example:

In this example there are two invoked operations: resize with argument 200x and rotate with argument 90.

You can arrange operations in sequences (i.e. “pipe” them). Such sequences also specify the execution order of operations. Please note that you can use any operation several times.

Finally, you can complete the URL with any chunk you wish, make sure not to add a slash in the end! It can be useful if your content editing system checks links for “extensions” or if you want to provide your users with nicer links. It might also be useful in terms of SEO.

Image Operations

It often happens that you need several versions of some image, say of different sizes or with effects applied. There are multiple on-the-fly processing routines in CDN API for that purpose.

Note that even though there are multiple input image formats supported by the CDN (such as JPEG, PNG, GIF, TIFF, BMP and more), the output format is set to PNG for images with transparency and JPEG for others.

CDN supports the following image operations:



Converting an image to one of the following formats:

  • jpeg — JPEG is a lossy image format (good compression, good for photos). JPEG doesn’t support an alpha channel, hence it’s better to be used with the setfill operation which sets a background color. The format is supported by all browsers.
  • png — PNG is a lossless format (good compression only for graphics) with an alpha channel support. Supported by all browsers.
  • webp — WebP is a modern image format which supports an alpha channel and a lossy compression. Suits any kinds of images. Note, the format is supported in a limited number of browsers.
  • auto — either jpeg or png format would be chosen depending on the presence of an alpha channel in an input.

400x301 png 116Kb

400x301 jpeg 16Kb

400x301 webp 15Kb,
Transparent, of the
same size as the opaque one.

In HTML 5, you can force the browser to automatically choose a WebP image version over others. This is done by using the <picture> element. Simply, wrap your <img> element with <picture> and add <source> having its type set to type="image/webp". Compatible browsers will then automatically load the WebP image version, others will take either JPEG or PNG.

  <source srcset="//" type="image/webp">
  <img src="//">



Setting the level of image quality. Image quality affects file sizes and hence loading speeds and amounts of generated traffic.

This operation affects JPEG and WebP images (without altering the source image format).

  • normal — the default setting, is fine in most cases.
  • better — can be used to render relatively small and detailed previews. ≈125% file size compared to the normal quality.
  • best — useful for hi-res images such as photos in case you want to get perfect quality without paying attention to file size. ≈170% file size.
  • lighter — is especially useful when applied to relatively large images in order to save traffic without significant losses in quality. ≈80% file size.
  • lightest — useful for retina resolutions, when you don’t have to worry about the quality of each individual pixel. ≈50% file size.

1x best 16Kb
Blurry on retina displays.

1.5x lighter 16Kb
Still a good fit for all screens.

2x lightest 16Kb
Perfect for retina.



Returns a progressive image. In progressive images, data is compressed in multiple passes of progressively higher detail. This is ideal for large images that will be displayed while downloading over a slow connection, allowing a reasonable preview after receiving only a portion of the data. The operation has no effect on non-JPEG images; does not force an image format to JPEG.

Baseline loading.

Progressive loading.



Reduces an image proportionally in order for it to fit into the given dimensions (in pixels). If dimensions are not specified then the default limits will be used (2048x2048 pixels).




Resizes an image to fit into the specified dimensions. If only a single linear dimension is specified, resizing is performed according to the specified size (aspect ratio is preserved).




Crops an image to specified dimensions, with specified offset. If no offset value is passed into the operation, the top-left corner of an image is used.

Original image.



If given dimensions are greater than the ones of the original image, then the whole image will be rendered inside a color-filled box. The color can be changed using the setfill method.



Scales down an image until one of the dimensions gets equal to the specified one, the rest is cropped. This is really useful when your goal is to fit into a box as much of an image as possible. Let us compare the two resizing methods:

Requested size.

Adjusted size.

Requested size.



Sets the behavior of the resize operation if a source image is smaller than the specified (resulting) dimensions. The following modes might be used to set the behavior:

  • on — stretches an image up. Default.
  • off — forbids stretching of an image along any dimension that exceeds the one of an image in size.
  • fill — the image isn’t stretched, but the color-filled frame is rendered around it (default fill color is used).






Sets the fill color used with crop or when converting an image with alpha channel to JPEG. The operation uses hexadecimal notation to define colors.






Auto-enhances an image by performing the following operations: auto levels, auto contrast, and saturation sharpening. :strength parameter values should be in the range from 0 to 100. The default value is 50.

Original image. 28Kb

/enhance/50/ 33Kb

/enhance/100/ 38Kb



Sharpens an image, might be especially useful in case of post-downscale images. :strength can be in the range from 0 to 20 and defaults to the value of 5.

The downscaled image. 13Kb

/sharp/10/ 16Kb

/sharp/20/ 18Kb



Blurs an image by the :strength factor. The filtering mode is Gaussian Blur, where :strength parameter sets the blur radius — effect intensity (technically :strength controls the Gaussian Blur standard deviation multiplied by ten). The value of :strength might come up to 5000, while the default value is 10. Please note, that the actual :strength value does not affect the speed of blur operation.

Original image. 16Kb

/blur/20/ 8Kb

/blur/100/ 6Kb


Desaturates an image. The operation has no additional parameters and simply produces a grayscale image output when applied.

Original image.



Inverts an image, rendering a 'negative' of the input image.

Original image.




The default behavior of our CDN is to parse EXIF tags of the original images and rotate them accordingly to the value of the “Orientation” tag. This is what we call autorotation. -/autorotate/no/ allows to turn off the default behavior.





Right-angle image rotation, counterclockwise. The value of :angle parameter must be a multiple of 90.

Original image.





Flips an image.

Original image.



Mirrors an image.

Original image.




This operation allows for a superimposement (or layering) of images. One of the most common uses of the operation are watermarks (i.e. semi-transparent images layered over opaque ones in order to complicate their unauthorized usage, etc.).

  • :uuid — UUID of the overlay image, a unique internal identifier of an image subjected to processing. Please note, that in order to be recognized by :uuid your image should be related to your account (any project of your account);
  • :relative_dimensions — linear dimensions of the overlay image. Please note that the aspect ratio of the overlay image is preserved. Hence, what you set is a maximum linear size along one of the axes (for example, -/overlay/:uuid/50%x50%/ means that any linear dimension of the overlay can not exceed 50% in size). Default size setting is 100%;
  • :relative_coordinates — position of the overlay over an input image. By default, the overlay is positioned in the top-left corner of an input. Coordinates represent an offset along each of the axes in either pixel or percent format. In general the coordinate system is designed in similarity with CSS background-position;
  • :opacity — opacity of the overlay in percent format. Please note, that overlay data might be initially semi-transparent or made to be so by tuning the opacity parameter.

Since % is an escape char in URLs, it can’t be used as-is and should be replaced with either %25 escape sequence or a p char (which is a more readable and concise option).

Moreover, every overlay setting is optional and can be omitted (make sure not to alter the sequence of settings, though)!

An example with specified size and opacity, positioning is omitted.

Here, size and position are specified while opacity setting is omitted.

As you see, multiple overlays can be added to an image,
here’s an example where similar overlays are added with varying position.



The operation allows for extracting the given number of prevailing colors from an image. It may prove useful when trying to analyze the dominant colors of a product present in a web store database, etc.

Please keep in mind that the main_colors operation should come last in the URL.

Technically, the operation is an optimized variation of the Local K-means color image quantization algorithm. The algorithm used is adapted to a wide variety of input image data, and provides results, intuitive in terms of human perception.

:number_of_colors — a number of colors you’d like to extract from an image (a smaller palette is derived, consisting of colors that are a fine match when representing the input image). :number_of_colors parameter may be omitted, the default value of 4 is used then.

main_colors operation returns a JSON, containing an array of 8-bit RGB values specific to the dominant colors. For example, for this input image, the operation with no specified parameters, i.e., will return this JSON,

  "width": 2000,
  "main_colors": [
    [138, 142, 143],
    [85, 74, 65],
    [193, 211, 224],
    [49, 42, 36]
  "height": 2000,
  "id": "/153d750a-049f-44dc-8372-853f49320bad/-/preview/",
  "original": {
    "width": 2000,
    "geo_location": null,
    "orientation": null,
    "datetime_original": null,
    "format": "JPEG",
    "id": "153d750a-049f-44dc-8372-853f49320bad",
    "height": 2000

Please note, that the algorithm uses random number generation, which may lead to slightly different results when performed on a single image repeatedly.

Other operations

This set of operations can be applied to both images and other file types. Please note that you can mix the operations from this set with the others (non-image operations should be placed last in a chain).



By default CDN instructs browsers to show images and to download other file types. By using this setting one can change the default behavior.




Returns image-related information (such as image dimensions or geotagging data) in JSON format.


In last case json response will contain original key with information about original image.



Same as the above, but returns data as application/javascript type. Callback name should always be uploadcare_callback. It should receive the two following arguments: id and response object. For original files, id is equivalent to the file UUID. For processed files id is equivalent to the path excluding last operation (JSONP).


In the first case id will be c5b7dd84-c0e2-48ff-babc-d23939f2c6b4, in the second — /c5b7dd84-c0e2-48ff-babc-d23939f2c6b4/-/preview/.

GIF to Video

This feature is experimental: it’s disabled by default. Shoot us a note to set it up for your project.


gif2video converts GIF files to video on the fly. Video files are generally much smaller than GIFs hence their delivery to the end user is much faster. In case your source file is not an animated GIF or the conversion feature is disabled for your project, you’ll get an HTTP 400 error.

Please note, gif2video is not an operation and thus it’s not divided from file UUID by the usual /-/ separator. However, gif2video can be combined with specific operations designed for it:



Converts an animated GIF to one of the following formats:

  • mp4 — H.264 video format. The format is supported by all major browsers. When no format is specified, mp4 is used by default.
  • webm — WebM video format. Supported in Google Chrome, Firefox and Opera.

When embedding videos, the best practice is to specify both formats and let clients choose a more suitable one.

<video width="384" height="216" autoplay loop muted webkit-playsinline playsinline>
  <source src="" type="video/webm">
  <source src="" type="video/mp4">

Original GIF: 6.5MB, MP4: 251KB, WebM: 202KB



Sets both quality and compression ratio for the output video. There are five :value levels: from better compression to better quality:
lightest, lighter, normal, better, best.

When quality is not specified, normal is used by default.

Detect Faces


Please note, detect_faces is not an operation and thus it’s not divided from file UUID by the usual /-/ separator. Hence, detect_faces can only be used by itself without piping with other operations, e.g. image processing.

detect_faces returns coordinates of faces found in an input image. The output is similar to the json operation. It produces a JSON with the additional list, faces, holding coordinates of faces that were detected. Data for each of the found faces are put into separate lists that look like this,

[x, y, x_size, y_size]

Further, lists within faces contain:

  • x, y — coordinates of the upper-left corner of an area where a face was found.
  • x_size, y_size — dimensions of the area.

For example, Let’s run a face-check for this image loaded to our CDN,

In order to do so, we put detect_faces into the image URL separating it with / from the UUID,

Then, this faces list will reside in the resulting JSON,

"faces": [
  [45, 142, 207, 207],
  [460, 113, 238, 238],
  [892, 43, 265, 265]

Technically, the operation detects faces using Haar Cascades. That approach deals with machine learning processes which rely on classifiers holding cascades of features specific to faces, eyes, etc.

detect_faces uses an algorithm that tends to better detect fronts of faces, rather than facial profiles. Also, covering important face features with different objects leads to a decline in detection accuracy.

detect_faces operation is still subject to testing and recalibrating the backend when needed. So, if you ran into any issue with the operation or simply got questions — hit us up.


This section describes the limitations one should consider using the CDN API.

  • Please note that while using any of the operations, you should also use at least one of the following: resize, scale_crop or preview. If you aren’t willing to affect the size of an image and only mean to auto rotate it and convert to one of the formats supported by a client browser, please use the preview control with no arguments;
  • The dimensions you specify for the last operation should not exceed 3000x3000 pixels. You can increase that limit to 5000x5000 pixels by explicitly setting your image format to JPEG in URL, /format/jpeg/;
  • Animated images are be treated as static;
  • We don’t provide on-the-fly image operations for huge images (greater than 75 Mpx in resolution) and for files uploaded in the multipart mode, see widget options, those can only be delivered via CDN as-is.

Group API

Groups are how you can organize files in a project. For instance, a group is created when you select multiple files to upload using our widget. A single file in a group can still be addressed using it’s UUID, the same is also working for groups — those can be invoked via a group UUID.

Files in group

You can request any file in a group by using it’s index (zero based):


Please note that there is no /-/ separator after a group UUID (/nth/ is not an operation). Group UUID always includes a number of files within this group, this way you can iterate through all of the files in a group. Files stored within a group still have support for all the operations.


If CDN operations have already been applied to a file before it was added to a group — the list of such operations is added to a group together with the file itself. So that if you request the file from a group, it’s going to be invoked with all of the stored operations. Hence, adding more controls to such file will result in combining them with the existing ones.


The operation lets you get a group as an archive.

Current limits are:

  • Total size of uncompressed files in a group should not exceed 100 MB
  • CDN API operations within a group are discarded: only original versions of files are added to the archive

archive workflow is straightforward:

  • :group_uuid — UUID of a file group you'd like to download as an archive.
  • :format — output archive format, we support zip and tar.
  • :filename — (optional) output filename: you can either specify a name for your archive or omit the parameter.


Gallery is a way to render a group of images on a single page. The gallery feature is powered by the Fotorama javascript library.


You can customize the layout and behavior of images in a gallery by adding operations to its URL (the workflow is pretty much the same as with files, see Fotorama options, except that we don’t support size, width/height and ratio manipulations here).


One of the great applications of the gallery feature might be embedding a collection of images right into your page via <iframe>!