Upload images

Cloudinary is a cloud-based service that provides an end-to-end image management solution, including upload, storage, administration, manipulation, optimization and delivery.

With Cloudinary you can easily upload images to the cloud and automatically perform smart image manipulations without installing any complex software. Cloudinary provides a secure and comprehensive API for easily uploading images from server-side code, directly from the browser or from a mobile application. You can either use Cloudinary's API directly or through one of Cloudinary's client libraries (SDKs), which wrap the upload API and simplify integration with web sites and mobile applications.

The uploaded images can then be automatically converted to all relevant formats suitable for web viewing, optimized for web browsers and mobile devices, normalized, manipulated in real time, and delivered through a fast CDN to users (see the image transformations documentation for more information).

While uploading images you can also apply transformations (e.g. changing dimensions or format) and assign tags to them, and you can manage all uploaded images using Cloudinary's Media Library web interface and the Admin API.

Cloudinary’s image management service enables image upload as follows:

See the Upload method of the API for all parameters available for uploading images.

Uploading images to the cloud

Uploading is done over HTTPS using a secure protocol based on your account's cloud_name, api_key and api_secret parameters, or using an unsigned upload without an authentication signature. When using Cloudinary's SDKs, the 3 security parameters are generally configured globally, but they can be provided with each call instead.

While you can use the API directly within your custom code, it is simpler and recommended to use Cloudinary's SDKs. We encourage using our client-side libraries for easy uploading:

The Cloudinary upload method performs an authenticated upload API call over HTTPS while sending the image file:

Ruby:
Cloudinary::Uploader.upload(file, options = {})
PHP:
\Cloudinary\Uploader::upload($file, $options = array());
Python:
cloudinary.uploader.upload(file, **options)
Node.js:
cloudinary.v2.uploader.upload(file, options, callback);
Java:
cloudinary.uploader().upload(Object file, Map options);

For example, uploading a local image file named sample.jpg:

Ruby:
Cloudinary::Uploader.upload("sample.jpg")
PHP:
\Cloudinary\Uploader::upload("sample.jpg");
Python:
cloudinary.uploader.upload("sample.jpg")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", ObjectUtils.emptyMap());

Uploading is performed synchronously, and once finished, the uploaded image is immediately available for manipulation and delivery.

Public ID - the image identifier

Every image uploaded to Cloudinary is assigned a unique identifier in the form of a Public ID, which is a URL-safe string that is used to reference the uploaded resource as well as for building dynamic delivery and transformation URLs. You can also browse and search resources by Public IDs in Cloudinary's Media Library web interface.

If you don't supply a Public ID in the upload API call, you will receive a randomly assigned Public ID in the response from the upload API call. A randomly generated public_id will look something like this: 8jsb1xofxdqamu2rzwt9q. As a result, the URL for accessing this image via our demo account would be:

http://res.cloudinary.com/demo/image/upload/8jsb1xofxdqamu2rzwt9q.jpg

The public_id parameter can be assigned by you while uploading the image, which is useful when you want your delivery URLs to be readable and refer to the associated entity. For example:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :public_id => "sample_id")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("public_id" => "sample_id"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    public_id = "sample_id")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { public_id: "sample_id" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("public_id", "sample_id"));

The Public ID can also be organized in folders for more structured delivery URLs, and Public IDs can include multiple folders: simply separate elements in your Public ID string with slashes (/). For example:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :public_id => "my_folder/my_sub_folder/my_name")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("public_id" => "my_folder/my_sub_folder/my_name"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    public_id = "my_folder/my_sub_folder/my_name")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { public_id: "my_folder/my_sub_folder/my_name" },
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("public_id", "my_folder/my_sub_folder/my_name"));

This can also be done by splitting the Public ID into 2 parts and also specifying the folder parameter. Using the same example as above, but this time with the folder parameter:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :folder => "my_folder/my_sub_folder/", :public_id => "my_name")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("folder" => "my_folder/my_sub_folder/", "public_id" => "my_name"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    folder = "my_folder/my_sub_folder/", public_id = "my_name")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { folder: "my_folder/my_sub_folder/", public_id: "my_name" },
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("folder", "my_folder/my_sub_folder/", "public_id", "my_name"));

For details on delivering Public IDs in a folder structure with or without versions, see Image versions.

To tell Cloudinary to use the original name of the uploaded image file as its Public ID, include the use_filename parameter and set it to true. Note that the file name will be normalized to include only URL-safe characters, and a set of random characters will also be appended to ensure the uniqueness of the Public ID. Also including the unique_filename parameter and setting it to false will tell Cloudinary not to attempt to make the Public ID unique, and just use the normalized file name. The following code example will upload the image file called sample_file.jpg and ensure that the Public ID of the uploaded image is set to sample_file:

Ruby:
Cloudinary::Uploader.upload("sample_file.jpg", 
    :use_filename => true, :unique_filename => false)
PHP:
\Cloudinary\Uploader::upload("sample_file.jpg", 
    array("use_filename" => TRUE, "unique_filename" => FALSE));
Python:
cloudinary.uploader.upload("sample_file.jpg", 
    "use_filename" = 1, "unique_filename" = 0)
Node.js:
cloudinary.v2.uploader.upload("sample_file.jpg",
    { use_filename: true, unique_filename: false },
    function(error, result) { console.log(result); });
Java:
cloudinary.uploader().upload("sample_file.jpg",
    ObjectUtils.asMap("transformation", 
    new Transformation().use_filename(true).unique_filename(false)));

Multiple derived images created by transformations of an uploaded image share the same Public ID as the uploaded image. They are further identified by the specific transformation that created them (see the image transformations documentation for more information).

Note that the Public ID format only supports alphanumeric characters, dashes (-), periods (.) and underscores (_).

Data upload options

Cloudinary supports uploading files from various sources, including a local path, a remote HTTP or HTTPS URL, a remote S3 URL, a Data URI or an FTP URL.

You can upload an image by specifying the local path of an image file. This option is only available when using Cloudinary's SDKs. For example:

Ruby:
Cloudinary::Uploader.upload("/home/sample.jpg")
PHP:
\Cloudinary\Uploader::upload("/home/sample.jpg");
Python:
cloudinary.uploader.upload("/home/sample.jpg")
Node.js:
cloudinary.v2.uploader.upload("/home/sample.jpg", 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("/home/sample.jpg", ObjectUtils.emptyMap());

If your images are already publicly available online, you can specify their remote HTTP or HTTPS URLs instead of uploading the actual data. In this case, Cloudinary will fetch the image from its remote URL for you. This option allows for a much faster migration of your existing images. For example:

Ruby:
Cloudinary::Uploader.upload("http://www.example.com/sample.jpg")
PHP:
\Cloudinary\Uploader::upload("http://www.example.com/sample.jpg");
Python:
cloudinary.uploader.upload("http://www.example.com/sample.jpg")
Node.js:
cloudinary.v2.uploader.upload("http://www.example.com/sample.jpg", 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("http://www.example.com/sample.jpg", ObjectUtils.emptyMap());

If you have existing images in an Amazon S3 bucket, you can point Cloudinary to their S3 URLs. Note - this option requires a quick manual setup. Contact us and we'll guide you on how to allow Cloudinary access to your relevant S3 buckets.

Ruby:
Cloudinary::Uploader.upload("s3://my-bucket/my-path/sample.jpg")
PHP:
\Cloudinary\Uploader::upload("s3://my-bucket/my-path/sample.jpg");
Python:
cloudinary.uploader.upload("s3://my-bucket/my-path/sample.jpg")
Node.js:
cloudinary.v2.uploader.upload("s3://my-bucket/my-path/sample.jpg", 
    function(error, result) { console.log(result); });
Java:
cloudinary.uploader().upload("s3://my-bucket/my-path/sample.jpg", ObjectUtils.emptyMap());

You can upload an image by specifying the Data URI in Base 64 encoding of an image file (no larger than 60 MB). For example:

Ruby:
Cloudinary::Uploader.upload("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==")
PHP:
\Cloudinary\Uploader::upload("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==");
Python:
cloudinary.uploader.upload("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==")
Node.js:
cloudinary.v2.uploader.upload("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", ObjectUtils.emptyMap());

You can upload an image by specifying a remote FTP URL. For private FTP servers, the username and password must be included as parameters with the URL syntax taking the form: ftp://<user>:<password>@<host>:<port>/<url-path>. For example:

Ruby:
Cloudinary::Uploader.upload("ftp://user1:mypass@ftp.example.com/sample.jpg")
PHP:
\Cloudinary\Uploader::upload("ftp://user1:mypass@ftp.example.com/sample.jpg");
Python:
cloudinary.uploader.upload("ftp://user1:mypass@ftp.example.com/sample.jpg")
Node.js:
cloudinary.v2.uploader.upload("ftp://user1:mypass@ftp.example.com/sample.jpg", 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("ftp://user1:mypass@ftp.example.com/sample.jpg", ObjectUtils.emptyMap());

Image versions

When you upload a new image while specifying its public_id to be the same as an existing image, your Cloudinary account will be updated with the new image overwriting the old one. However, if the original (older) image has already been accessed, it might already be cached in the CDN: if you access the exact same URL you will still be accessing a CDN cached version rather than the new updated one.

The version component is an optional part of the delivery URL that can be added in order to bypass the CDN cached version and force delivery of the newest image. Cloudinary returns the value of the version parameter as part of every upload response, and the returned url and secure_url parameters also include the version component, which represents the timestamp of the upload. For example:

Example image delivery URL without version:

http://res.cloudinary.com/demo/image/upload/sample.jpg

Example image delivery URL with version:

http://res.cloudinary.com/demo/image/upload/v1371750447/sample.jpg

As an alternative to using versions, you can set the invalidate parameter to true while uploading a new image in order to invalidate the previous image throughout the CDN. Note that it usually takes a few minutes (although it might take up to an hour) for the invalidation to fully propagate through the CDN, while the version component takes effect immediately.

Note: There are also a number of other important considerations when using the invalidate functionality. For example, if there is no version number in a URL that includes a folder structure, then by default, those URLs are not invalidated. For details on invalidating images, see Invalidating cached images on the CDN.

Chunked image upload

In order to support the upload of large image files, the cloudinary SDKs include a method which offers a degree of tolerance for network issues. The upload_large method uploads a large image to the cloud in chunks, and is required for any files that are larger than 100 MB. Note that files are uploaded as raw files by default if the resource_type parameter is not specified:

Ruby:
Cloudinary::Uploader.upload_large(file)
PHP:
\Cloudinary\Uploader::upload_large(file);
Python:
cloudinary.uploader.upload_large(file)
Node.js:
cloudinary.v2.uploader.upload_large(file, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().uploadLarge(file);

For example, uploading a large image file named my_large_image.tiff:

Ruby:
Cloudinary::Uploader.upload_large("my_large_image.tiff", 
    :resource_type => "image")
PHP:
\Cloudinary\Uploader::upload_large("my_large_image.tiff",
    array("resource_type" => "image"));
Python:
cloudinary.uploader.upload_large("my_large_image.tiff", 
    resource_type = "image")
Node.js:
cloudinary.v2.uploader.upload_large("my_large_image.tiff", 
    { resource_type: "image" },
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().uploadLarge("my_large_image.tiff",
    ObjectUtils.asMap("resource_type", "image"));

By default, the chunk size is set to 20 Megabytes but can be set to as low as 5 Megabytes by using the chunk_size parameter. For example, uploading a large image file named my_large_image.tiff and setting chunk size to 6 Megabytes:

Ruby:
Cloudinary::Uploader.upload_large("my_large_image.tiff",
    :resource_type => "image", :chunk_size => 6_000_000)
PHP:
\Cloudinary\Uploader::upload_large("my_large_image.tiff", 
    array("resource_type" => "image", "chunk_size" => 6000000));
Python:
cloudinary.uploader.upload_large("my_large_image.tiff", 
    resource_type = "image", chunk_size = 6000000)
Node.js:
cloudinary.v2.uploader.upload_large("my_large_image.tiff", 
    { resource_type: "image", chunk_size: 6000000 }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().uploadLarge("my_large_image.tiff",
    ObjectUtils.asMap("resource_type", "image", "chunk_size", 6000000));

Note: The upload_large method is supported only in the Cloudinary SDKs. When directly calling the API, you can make use of the byte Content-Range entity-header HTTP specification to send the file in multiple calls.

Upload response

An upload API call returns a response that includes the HTTP and HTTPS URLs for accessing the uploaded image, as well as additional information regarding the uploaded image: The Public ID and current version of the image (used in the Media Library, Admin API, and for building manipulation and delivery URLs), the image's dimensions, the image format and a signature for verifying the response. The following is an example of the JSON response returned:

{
 url: 'http://res.cloudinary.com/demo/image/upload/v1312461204/sample.jpg',
 secure_url: 'https://res.cloudinary.com/demo/image/upload/v1312461204/sample.jpg',
 public_id: 'sample',
 version: '1312461204',
 width: 864,
 height: 564,
 format: 'jpg',
 created_at: '2015-10-10T09:55:32Z',
 resource_type: 'image',
 tags: [], 
 bytes: 9597, 
 type: 'upload', 
 etag: 'd1ac0ee70a9a36b14887aca7f7211737', 
 signature: 'abcdefgc024acceb1c1baa8dca46717137fa5ae0c3',
 original_filename: 'sample'
}

For more information on uploading images from server side code for specific frameworks, see Ruby on Rails, PHP, Django, Node.js, Java or .NET.

Backups and revisions

In addition to safely storing uploaded images in a cloud based storage (leveraging Amazon’s S3 service), images can be automatically backed up to a safer location, where no API calls can penetrate. In addition, Cloudinary keeps multiple revisions for each uploaded resource for even greater robustness.

By default, backup is turned off. Enabling automatic backup means that every uploaded file is also copied to a secondary write-protected location, while keeping multiple revisions per file (increasing the storage used). To enable backup of your Cloudinary-managed resources, simply open your management console and enable backup through the Upload tab on the Settings page. Changes will take effect immediately for all newly uploaded images.

Note that remotely fetched images, including Facebook and Twitter profile pictures, are not backed up because they can be automatically re-created at any time. In addition, Cloudinary keeps backup copies only for your original images and not of the derived (transformed) versions of these originals, as these too can be re-generated on demand.

You can also selectively override the global backup setting when uploading a specific file by specifying the backup boolean parameter in the upload API call. For example, with the global backup setting not enabled, adding the backup parameter and setting it to true when uploading the file sample.jpg, will ensure that the file is backed-up:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :backup => true)
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("backup" => true));
Python:
cloudinary.uploader.upload("sample.jpg", 
    backup = true)
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { backup: true }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("backup", true));

In the Media Library, backed-up resources are marked with a small gray safe icon.

screenshot of backup in media library

A red safe icon means that a file has additional historical revisions and clicking on the View backed up versions button will list all the revisions. To view a specific previous version of the image, click on its version number link, and to restore a previous version, click on the Restore link next to the listed version.

Direct uploading from the browser or mobile application

The upload samples shown above allow your code to upload images to Cloudinary. In this flow, if you have a web form that allows your users to upload images, the image data is first sent to your server and only then uploaded to Cloudinary.

A more efficient and powerful option is to allow your users to upload images directly from the browser or a mobile application instead of going through your servers. This method allows for faster uploading and better user experience for your visitors. It also reduces load from your servers and reduces the complexity of your applications.

Uploading directly from the browser is enabled by Cloudinary's jQuery plugin, which requires a small setup: including jQuery, Cloudinary's jQuery plugin, jQuery-File-Upload plugin files and defining your cloud name and API Key. For more information on direct uploading from the browser see Ruby on Rails, PHP, Django, Node.js, Java, .NET, or jQuery and the blog post on Direct upload made easy, from browser or mobile app to the cloud.

Activate signed client side image uploading by embedding an upload input field in your HTML pages. The Cloudinary SDKs have helper methods (e.g., the cl_image_upload_tag method) that automatically add a file input field to your form. Selecting or dragging a file to this input field will automatically initiate uploading from the browser to Cloudinary. For example, using Ruby on Rails (other frameworks use the same concept):

cl_image_upload_tag(:image_id, options = {})

When uploading is completed, the identifier of the uploaded image is set as the value of the given input field in your HTML page (the image_id parameter in the example above). You can then process the identifier received by your controller and store it for future use, exactly as if you're using a standard server side uploading.

Note: If you manually create your own file input field (i.e., you don't use one of Cloudinary's helper methods), make sure to include the name="file" attribute in the input field (e.g., <input id="upload-img" type="file" name="file">)

Unsigned upload

Unsigned upload is an option for performing upload directly from a browser or mobile application with no authentication signature, and without going through your servers at all. However, for security reasons, not all upload parameters can be specified directly when performing unsigned upload calls.

Unsigned upload options are controlled by an upload preset, so in order to use this feature you first need to enable unsigned uploading for your Cloudinary account from the Upload Settings page. Enabling unsigned uploading also creates an upload preset with a unique name, which explicitly allows uploading of images without authentication. The preset is also used to define which upload options will be applied to images that are uploaded unsigned with that preset specified. You can edit the preset at any point in time (or create additional upload presets), to define the parameters that will be used for all images that are uploaded unsigned from user browsers or mobile applications.

For more information on upload presets, see the upload preset documentation and the Centralized control for image upload blog post.

In order to perform an unsigned upload, simply call the unsigned_upload method of the Cloudinary SDKs while setting the upload_preset and cloud_name parameters. For example, to upload the sample.jpg file to the Cloudinary demo account with the unsigned_1 upload preset:

Ruby:
Cloudinary::Uploader.unsigned_upload("sample.jpg", "unsigned_1", 
    :cloud_name => "demo")
PHP:
\Cloudinary\Uploader::unsigned_upload("sample.jpg", "unsigned_1", 
    array("cloud_name" => "demo"));
Python:
cloudinary.uploader.unsigned_upload("sample.jpg", "unsigned_1", 
    cloud_name = 'demo')
Node.js:
cloudinary.v2.uploader.unsigned_upload("sample.jpg", "unsigned_1", 
    { cloud_name: "demo" }, 
    function(error, result) {console.log(result) });
Java:
cloudinary.uploader().unsignedUpload("sample.jpg", "unsigned_1",
    ObjectUtils.asMap("cloud_name", "demo"));

Note: For security reasons, only this limited set of parameters can be used in an unsigned upload request.

Upload multiple images

The file input field can be configured to support multiple file uploading simultaneously by setting the multiple HTML parameter to true. You should manually bind to the cloudinarydone event to handle the results of multiple uploads. Here's an example:

Ruby:
<%= cl_image_upload_tag(:image_id, 
    :html => { :multiple => true }) %>
PHP:
<?php echo cl_image_upload_tag("image_id", 
    array("html" => array("multiple" => TRUE ))); ?>
Python:
image = CloudinaryJsFileField(
    attrs = { 'multiple': 1 })
Node.js:
cloudinary.uploader.image_upload_tag(
    'image_id', { html: { multiple: 1 } });
Java:
String html = cloudinary.uploader().imageUploadTag("image_id", 
    ObjectUtils.asMap("multiple", true));

Display preview thumbnails and indicate upload progress

Cloudinary's jQuery library also enables an enhanced uploading experience - show a progress bar, display a thumbnail of the uploaded image, drag & drop support and more.

Bind to Cloudinary's cloudinarydone event if you want to be notified when an upload to Cloudinary has completed. You will have access to the full details of the uploaded image and you can display a cloud-generated thumbnail of the uploaded images using Cloudinary's jQuery plugin.

The following sample code creates a 150x100 thumbnail of an uploaded image and updates an input field with the Public ID of this image.

$('.cloudinary-fileupload').bind('cloudinarydone', function(e, data) {  
  $('.preview').html(
    $.cloudinary.image(data.result.public_id, 
      { format: data.result.format, version: data.result.version, 
        crop: 'fill', width: 150, height: 100 })
  );    
  $('.image_public_id').val(data.result.public_id);    
  return true;
});

You can track the upload progress by binding to the following events: fileuploadsend, fileuploadprogress, fileuploaddone and fileuploadfail. You can find more details and options in the documention of jQuery-File-Upload.

The following Javascript code updates a progress bar according to the data of the fileuploadprogress event:

$('.cloudinary-fileupload').bind('fileuploadprogress', function(e, data) { 
    $('.progress_bar').css('width', Math.round((data.loaded * 100.0) / data.total) + '%'); 
});

You can find some more examples as well as an upload button style customization in our Photo Album sample project.

For more details about direct uploading, see the following blog posts: Direct image uploads from the browser to the cloud with jQuery and Direct upload made easy, from browser or mobile app to the cloud

Deleting client-side uploaded images

The Cloudinary jQuery library supports using a delete token to delete images on the client-side for a limited time of 10 minutes after being uploaded. After 10 minutes has passed, the image cannot be deleted from the client side, only via the Destroy method of the Upload API (or using the Admin API).

In order to also receive a deletion token in the upload response, add the return_delete_token parameter to the upload method and set it to true. Note that this parameter is not supported when using unsigned uploads (although it can be set within the upload preset for the unsigned upload).

For example:

Ruby:
<%= cl_image_upload_tag(:image_id, 
    :return_delete_token => true) %>
PHP:
<?php echo cl_image_upload_tag("image_id", 
    array("return_delete_token" => TRUE )); ?>
Python:
image = CloudinaryJsFileField(
    options = { 'return_delete_token': 1 })
Node.js:
cloudinary.uploader.image_upload_tag('image_id', 
    { return_delete_token: 1 });
Java:
String html = cloudinary.uploader().imageUploadTag(
    "image_id", ObjectUtils.asMap("return_delete_token", true));

The delete_token returned in the upload response can be used to delete the uploaded image using the delete_by_token method of the jQuery library. For example:

$.cloudinary.delete_by_token(delete_token)

Upload widget

Cloudinary's upload widget is an interactive, feature rich, simple to integrate method to allow your users to upload images directly to Cloudinary. The widget eliminates the hassle of developing an in-house interactive image upload solution.

Cloudinary's upload widget includes a complete graphical interface and allows your website visitors to upload files from multiple sources, for example, one or more local images, a remote image (URL) or just snapping an image directly from the computer or mobile device's camera. The widget supports a drag & drop functionality, interactive cropping, upload progress indication and thumbnail previews, and also monitors and handles uploading errors. The upload widget's behavior can be configured and the look & feel can be customized.

upload widget

Cloudinary's upload widget requires pure Javascript to integrate and is easy to use with any web development framework. Advanced features are also available when using jQuery.

Integrating the widget in your site is very simple. Firstly, include the the remote Javascript file of the upload widget:

<script src="//widget.cloudinary.com/global/all.js" type="text/javascript"></script>

The upload widget can now be opened programmatically with, for example, the cloudinary.openUploadWidget method:

<script type="text/javascript">  
    cloudinary.openUploadWidget({ cloud_name: 'demo', upload_preset: 'a5vxnzbp'}, 
        function(error, result) { console.log(error, result) });
</script>

For more information and specific details, including the parameters used in the openUploadWidget method, see the Upload Widget documentation.

Eager transformations

Cloudinary can either manipulate your images on demand, on-the-fly, when accessed by your visitors as lazy transformations, or during the image upload process as eager transformations.

For lazy transformations, all transformed images are generated on-the-fly, stored persistently, cached and delivered through a fast CDN. The time required for generating a transformation depends on various factors: original image dimensions, image file size, requested dimensions, applied effects and specific transformations. Once generated for the first time on the first request of a visitor, the transformed image is henceforth cached and delivered through a fast CDN for all subsequent requests.

The eager approach requires a little planning, but is recommended if most of your images will be accessed by your visitors, and you want to make sure that all transformed images are ready for fast delivery even for the first visitors to your images. In this case, you can eagerly create the required transformations during the upload process so all transformed images will already be available before your users access them for the first time. Eager transformations are also useful in the case that you want to enable Strict Transformations for your account and limit access to dynamic URLs (for more information, see Control access to images).

The eager parameter accepts a list of transformations to create for the uploaded image during the upload process, instead of lazily creating them when first accessed by your site's visitors (see the Image manipulation reference documentation for more details on possible values). This option accepts either a single transformation or an array of transformations, where each transformation is represented by a hash of parameters.

For example, the following method will upload the sample.jpg image and then generate two transformed images as follows:

  1. Pad to a width of 400 pixels and height of 300 pixels.
  2. Crop to a width of 260 pixels and a height of 200 pixels with north gravity.
Ruby:
Cloudinary::Uploader.upload("sample.jpg",
    :eager => [
        {:width => 400, :height => 300, :crop => :pad}, 
        {:width => 260, :height => 200, :crop => :crop, :gravity => :north}])
PHP:
\Cloudinary\Uploader::upload("sample.jpg", array( 
    "eager" => array(
        array("width" => 400, "height" => 300, "crop" => "pad"),
        array("width" => 260, "height" => 200, "crop" => "crop", "gravity" => "north"))));
Python:
cloudinary.uploader.upload("sample.jpg", 
    eager = [
        {"width": 400, "height": 300, "crop": "pad"},
        {"width": 260, "height": 200, "crop": "crop", "gravity": "north"}])
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { eager: [
        { width: 400, height: 300, crop: "pad" }, 
        { width: 260, height: 200, crop: "crop", gravity: "north"} ]}, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap(
        "eager", Arrays.asList(
            new Transformation().width(400).height(300).crop("pad"),
            new Transformation().width(260).height(200).crop("crop").gravity("north"))));

The manipulation and delivery URLs for these eagerly generated transformations:

Ruby:
cl_image_tag("sample.jpg", :width=>400, :height=>300, :crop=>"pad")
PHP:
cl_image_tag("sample.jpg", array("width"=>400, "height"=>300, "crop"=>"pad"))
Python:
CloudinaryImage("sample.jpg").image(width=400, height=300, crop="pad")
Node.js:
cloudinary.image("sample.jpg", {width: 400, height: 300, crop: "pad"})
Java:
cloudinary.url().transformation(new Transformation().width(400).height(300).crop("pad")).imageTag("sample.jpg")
jQuery:
$.cloudinary.image("sample.jpg", {width: 400, height: 300, crop: "pad"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(400).Height(300).Crop("pad")).BuildImageTag("sample.jpg")
sample.jpg padded to a width of 400 pixels and height of 300 pixels

Ruby:
cl_image_tag("sample.jpg", :width=>260, :height=>200, :gravity=>"north", :crop=>"crop")
PHP:
cl_image_tag("sample.jpg", array("width"=>260, "height"=>200, "gravity"=>"north", "crop"=>"crop"))
Python:
CloudinaryImage("sample.jpg").image(width=260, height=200, gravity="north", crop="crop")
Node.js:
cloudinary.image("sample.jpg", {width: 260, height: 200, gravity: "north", crop: "crop"})
Java:
cloudinary.url().transformation(new Transformation().width(260).height(200).gravity("north").crop("crop")).imageTag("sample.jpg")
jQuery:
$.cloudinary.image("sample.jpg", {width: 260, height: 200, gravity: "north", crop: "crop"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(260).Height(200).Gravity("north").Crop("crop")).BuildImageTag("sample.jpg")
sample.jpg cropped to a width of 260 pixels and a height of 200 pixels with north gravity

Note: When using our upload API from within your custom code rather than from within our SDKs (see Uploading images with a direct call to the API for more information), the eager parameter receives a list of transformation strings separated with a pipe character (|). Chained transformations are separated with a slash (/). For example, the following eager value will generate two transformations: crop out a 400x400 region centered on the largest detected face and then scale down to a width and height of 50 pixels, and crop to a width and height of 30 pixels with south gravity:

eager=c_crop,w_400,h_400,g_face/w_50,h_50,c_scale|w_30,h_40,c_crop,g_south

To apply transformations to previously uploaded images use the explicit API method.

Incoming transformations

Images uploaded to Cloudinary are stored in the cloud as-is, by default. Once safely stored in the cloud, you can generate derived images from these originals by asking Cloudinary to apply transformations and manipulations.

Sometimes you may want to normalize and transform the original images before storing them in the cloud, by applying an incoming transformation as part of the upload request. Any image transformation parameter can be specified as an option in the upload call and these transformations are applied before saving the image in the cloud.

For example, to limit the dimensions of an uploaded image to a width of 2000 pixels and a height of 1000 pixels:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :width => 2000, :height => 1000, :crop => :limit)
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("width" => 2000, "height" => 1000, "crop" => "limit"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    "width" = 2000, "height" = 1000, "crop" = "limit")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg",
    { width: 2000, height: 1000, crop: "limit" },
    function(error, result) { console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg",
    ObjectUtils.asMap("transformation", 
        new Transformation().width(2000).height(1000).crop("limit")));

Note: When using the SDK for a dynamically-typed language, the transformation parameters can be specified directly, without specifying the transformation parameter, as seen for example in the examples for Ruby, PHP, Python, and Node.js above.

Notifications and asynchronous transformations

By default, Cloudinary's upload API works synchronously: uploaded images are processed and eager transformations are generated synchronously during the upload API call, which means that the original image and derived images are available immediately for delivery and further management. However, in some cases you may need to be notified that an upload has completed, or you may want to process actions asynchronously in the background, especially actions that require a relatively long time to process and require your users to actively wait for the processing to finish.

Cloudinary's notifications and background processing capabilities extend your image upload options with the following features:

Upload notifications

In specific situations, you may want to notify your backend as soon an upload completes, for example when dealing with user initiated uploads from a browser or mobile device. You can tell Cloudinary to notify your application as soon as the upload completes by adding the notification_url parameter to the upload method and setting it to any valid HTTP or HTTPS URL. You can also set the notification_url parameter globally for all uploads on the Upload Settings page in the Cloudinary Management Console, instead of individually for each upload call (the parameter is also used to notify your application when any requested asynchronous action is completed).

For example:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :notification_url => "http://mysite/my_notification_endpoint")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("notification_url" => "http://mysite/my_notification_endpoint"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    notification_url = "http://mysite/my_notification_endpoint")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { notification_url: "http://mysite/my_notification_endpoint" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("notification_url", "http://mysite/my_notification_endpoint"));

When the upload is completed, an HTTP POST request will be sent to the notification URL you provided. The post data will contain all the upload result details as returned by our upload API (Public ID, URLs, image dimensions, semantic data if requested and more). The request will also contain a signature of the sent data so you can verify the sender. The signature is calculated as follows:

SHA1-Hex-Digest("{data}{timestamp}{api_secret}")

Here's an example POST request sent by Cloudinary:

  POST /my_notification_endpoint HTTP/1.1
X-Cld-Timestamp: 1368881627
X-Cld-Signature: 29a383e289bc569310a8ca9899019a3167b4909e
Content-Type: application/json

Here's an example of the JSON of the upload result:

{
 "public_id": "djhoeaqcynvogt9xzbn9",
 "version": 1368881626,
 "width": 864,
 "height": 576,
 "format": "jpg",
 "resource_type": "image",
 "created_at": "2013-05-18T12:53:46Z",
 "bytes": 120253,
 "type": "upload",
 "url": "http://res.cloudinary.com/demo/image/upload/v1368881626/djhoeaqcynvogt9xzbn9.jpg",
 "secure_url": "https://res.cloudinary.com/demo/image/upload/v1368881626/djhoeaqcynvogt9xzbn9.jpg"}

Eager asynchronous transformations

You can tell Cloudinary to generate eager transformations in the background by setting the eager_async parameter to true. This is useful when you use direct image uploading from the browser and you don't want your users to have to wait for the transformation(s) to finish processing. In addition, you can set the optional eager_notification_url parameter to receive an HTTP POST request when the transformation generation is completed (see Upload notifications above for an example POST request).

The upload API of Cloudinary supports the following parameters for eager asynchronous transformations as follows:

  • eager - A list of transformations to create for the uploaded image during the upload process, instead of lazily creating them when first accessed by your site's visitors (see the Image manipulation reference documentation for more details on possible values). This option accepts either a single transformation or an array of transformations, where each transformation is represented by a hash of parameters.
  • eager_async - A Boolean value determining whether to generate the eager transformations asynchronously in the background after the file is finished uploading or synchronously as part of the upload call. Default: false.
  • eager_notification_url - An HTTP or HTTPS URL to notify your application (a webhook) when the generation of eager transformations is completed.

For example, the following method will upload the sample.jpg image and then eagerly generate two transformed images as follows:

  1. Pad to a width and height of 300 pixels.
  2. Crop to a width of 160 pixels and a height of 100 pixels with south gravity.

Furthermore, the transformations are to be done asynchronously after the image file finishes uploading, with a callback URL to notify your application once the upload is complete and a different callback URL to notify your application once the transformations are complete:

Ruby:
Cloudinary::Uploader.upload("sample.jpg",
    :eager => [
        {:width => 300, :height => 300, :crop => :pad}, 
        {:width => 160, :height => 100, :crop => :crop, :gravity => :south}], 
    :eager_async => true, 
    :eager_notification_url => "http://mysite/eager_endpoint",
    :notification_url => "http://mysite/upload_endpoint")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", array( 
    "eager" => array(
        array("width" => 300, "height" => 300, "crop" => "pad"),
        array("width" => 160, "height" => 100, "crop" => "crop", "gravity" => "south")),
    "eager_async" => TRUE,
    "eager_notification_url" => "http://mysite/eager_endpoint",
    "notification_url" => "http://mysite/upload_endpoint"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    eager = [
        {"width": 300, "height": 300, "crop": "pad"},
        {"width": 160, "height": 100, "crop": "crop", "gravity": "south"}],
    eager_async = true,
    eager_notification_url = "http://mysite/eager_endpoint",
    notification_url = "http://mysite/upload_endpoint")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { eager: [
        { width: 300, height: 300, crop: "pad" }, 
        { width: 160, height: 100, crop: "crop", gravity: "south"} ],                                   
      eager_async: true,
      eager_notification_url: "http://mysite/eager_endpoint",
      notification_url: "http://mysite/upload_endpoint" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap(
        "eager", Arrays.asList(
            new Transformation().width(300).height(300).crop("pad"),
            new Transformation().width(160).height(100).crop("crop").gravity("south")),
        "eager_async", true,
        "eager_notification_url", "http://mysite/eager_endpoint",
        "notification_url", "http://mysite/upload_endpoint"));

See the following blog post for more details: Webhooks, upload notifications and background image processing.

Uploading non-image files as raw files

Any type of file can be uploaded to Cloudinary, not just images or videos, e.g. CSS files, Javascripts, etc. Cloudinary offers a single solution to all uploads relevant to your website visitors, while delivering these files through a fast CDN.

Any file that is not an image or video file is treated as a 'raw' file, and means that these files are stored as-is when uploaded to Cloudinary. No transformations on uploaded raw files are currently available: you can simply access the uploaded files through a dynamic CDN URL in the same way you access images.

Uploading a raw file is accomplished in the same way as uploading an image file, with the addition of the resource_type parameter set to raw or auto (see below).

Ruby:
Cloudinary::Uploader.upload("sample_spreadsheet.xls", 
    :resource_type => :raw)
PHP:
\Cloudinary\Uploader::upload("sample_spreadsheet.xls", 
    array("resource_type" => "raw"));
Python:
cloudinary.uploader.upload("sample_spreadsheet.xls", 
    resource_type = "raw")
Node.js:
cloudinary.v2.uploader.upload("sample_spreadsheet.xls", 
    { resource_type: "raw" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample_spreadsheet.xls", 
    ObjectUtils.asMap("resource_type", "raw"));

Note: Although the Public IDs of image files do not include the file's extension, Public IDs of raw files do include the original file's extension.

Here's a sample response of a raw upload call, which is slightly different from an image upload response:

{
 "public_id": "sample_spreadsheet.xls",
 "version": 1371928603,
 "signature": "9088291a2c12202767cfa7c5e874afee72be78cd",
 "resource_type": "raw",
 "created_at": "2015-06-22T19:16:43Z",
 "tags": [],
 "bytes": 6144,
 "type": "upload",
 "etag": "107bf134b5afd11cc7544d60108d87b", 
 "url": "http://res.cloudinary.com/demo/raw/upload/v1371928603/sample_spreadsheet.xls",
 "secure_url": "https://res.cloudinary.com/demo/raw/upload/v1371928603/sample_spreadsheet.xls"
 "original_filename": "sample_spreadsheet"
}

Sometimes you don't know whether your users will upload image files, video files or raw files. In this case, you can set the resource_type parameter to auto and Cloudinary will automatically detect whether the uploaded file is an image, video or non-image raw file. When using direct image uploading from the browser, resource type is set to auto by default.

Ruby:
Cloudinary::Uploader.upload("sample_spreadsheet.xls", 
    :resource_type => :auto)
PHP:
\Cloudinary\Uploader::upload("sample_spreadsheet.xls", 
    array("resource_type" => "auto"));
Python:
cloudinary.uploader.upload("sample_spreadsheet.xls", 
    resource_type = "auto")
Node.js:
cloudinary.v2.uploader.upload("sample_spreadsheet.xls", 
    { resource_type: "auto" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample_spreadsheet.xls", 
    ObjectUtils.asMap("resource_type", "auto"));

Auto-fetching remote images

Instead of directly uploading images to your Cloudinary account, Cloudinary's "fetch" capabilities can automatically retrieve images from remote URLs. Auto Upload and Fetch are two similar features for automatically fetching (retrieving) images from existing remote locations using dynamic URLs. The images are delivered through a powerful CDN network, greatly improving your users’ browsing experience, reducing load on your servers and lowering hosting costs, while you also benefit from on-the-fly image manipulation and optimization, and all of this with minimum changes on your side. The main difference between these two features is how the remote image is handled:

  • Fetch enables on-the-fly manipulation of existing remote images and optimized delivery via a CDN. Fetched images are cached on your Cloudinary account for performance reasons.
  • Auto Upload also enables on-the-fly manipulation of existing remote images and optimized delivery via a CDN, while simultaneously uploading the image to your Cloudinary account for further management, and thus benefiting from a variety of additional features (just like any other image uploaded to your Cloudinary account).

The Fetch feature is a quick way to deliver images from remote URLs. The image can be manipulated and optimized on-the-fly, before being cached and delivered through fast, localized CDNs and not via local web servers. To create a Fetch URL, simply prepend the following prefix to the URL of the image:

http://res.cloudinary.com/<your Cloudinary account's cloud name>/image/fetch/

For example, to deliver a remote image of Jennifer Lawrence fetched by Cloudinary from WikiMedia (using Cloudinary's demo account):

Ruby:
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", :type=>"fetch")
PHP:
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", array("type"=>"fetch"))
Python:
CloudinaryImage("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg").image(type="fetch")
Node.js:
cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {type: "fetch"})
Java:
cloudinary.url().type("fetch").imageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
jQuery:
$.cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {type: "fetch"})
.Net:
cloudinary.Api.UrlImgUp.Type("fetch").BuildImageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
Remote image retrieved and delivered using fetch

The Auto Upload feature is implemented by mapping a base remote URL to a specified folder in the Upload Settings of the Management Console. Then, whenever accessing a Cloudinary delivery URL containing the folder prefix, any resources are automatically retrieved from the mapped URL if they are not already uploaded to the folder, and are available for further manipulation, management and CDN delivery like any other image uploaded to Cloudinary.

The Auto Upload URL takes the following structure:

http://res.cloudinary.com/<your Cloudinary account's cloud name>/image/upload/<mapped upload folder prefix>/<partial path of remote image>

For example, creating a folder called remote_media on your Cloudinary account and then mapping it to the URL prefix http://upload.wikimedia.org/wikipedia/ allows you to generate a Cloudinary delivery URL that substitutes the remote_media folder prefix for the URL prefix. Where the original URL is:

http://upload.wikimedia.org/wikipedia/commons/2/29/Marcelo_Facini.jpg

With the Auto Upload feature you would now access the following Cloudinary URL:

Ruby:
cl_image_tag("remote_media/commons/2/29/Marcelo_Facini.jpg")
PHP:
cl_image_tag("remote_media/commons/2/29/Marcelo_Facini.jpg")
Python:
CloudinaryImage("remote_media/commons/2/29/Marcelo_Facini.jpg").image()
Node.js:
cloudinary.image("remote_media/commons/2/29/Marcelo_Facini.jpg")
Java:
cloudinary.url().imageTag("remote_media/commons/2/29/Marcelo_Facini.jpg")
jQuery:
$.cloudinary.image("remote_media/commons/2/29/Marcelo_Facini.jpg")
.Net:
cloudinary.Api.UrlImgUp.BuildImageTag("remote_media/commons/2/29/Marcelo_Facini.jpg")
Auto upload with remote_media folder mapped to http://upload.wikimedia.org/wikipedia/

The image is dynamically retrieved the first time this URL is accessed and stored in your Cloudinary account with a Public ID of remote_media/commons/2/29/Marcelo_Facini.

For more information on the Auto Upload and Fetch features, see the detailed documentation on Fetching remote images, and the blog posts: Delivering all your websites’ images through a CDN and How to automatically migrate all your images to the cloud.

Moderation of uploaded images

It’s sometimes important to moderate images uploaded to Cloudinary: you might want to keep out inappropriate or offensive content, reject images that do not answer your website’s needs (e.g., making sure there are visible faces in profile images), or make sure that photos are of high enough quality before making them available on your website. Whether using the server-side upload API call, or when allowing users to upload the images directly from their browser, you can mark an image for moderation by adding the moderation parameter to the upload call. The parameter can be set to either:

For example, to mark an image for manual moderation:

Ruby:
Cloudinary::Uploader.upload("user_photo.jpg", 
    :moderation => 'manual')
PHP:
\Cloudinary\Uploader::upload("user_photo.jpg",
    array( "moderation" => "manual" ));
Python:
cloudinary.uploader.upload("user_photo.jpg",
    moderation = 'manual')
Node.js:
cloudinary.v2.uploader.upload("user_photo.jpg",
    { moderation: 'manual' },
    function(error, result) { console.log(result); });
Java:
cloudinary.uploader().upload("user_photo.jpg", 
    Cloudinary.asMap("moderation", "manual"));

Images that are uploaded to Cloudinary, and tagged for manual moderation, can be viewed by moderators using Cloudinary’s Media Library. Moderators can browse recently uploaded images and decide to accept or reject them.

Queue of pending images

You can also add a notification_url parameter while uploading the image, which instructs Cloudinary to notify your application of changes to moderation status, with the details of the moderation event (approval or rejection).

Ruby:
Cloudinary::Uploader.upload("sample.jpg",
    :moderation => "manual",
    :notification_url => "http://mysite/mod_endpoint")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", array( 
    "moderation" => "manual",
    "notification_url" => "http://mysite/mod_endpoint"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    moderation = "manual",
    notification_url = "http://mysite/mod_endpoint")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", { 
    moderation: "manual",
    notification_url: "http://mysite/mod_endpoint" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap(
        "moderation", "manual",
        "notification_url", "http://mysite/mod_endpoint"));

Furthermore, if an image is rejected, you can use Cloudinary’s default image mechanism to display a placeholder image instead using the default_image parameter (d for URLs) when delivering the image. See the Using default image placeholders documentation for more details.

See the blog post on Image moderation made easy using cloud-based UI and API for more information on manual moderation.

Semantic data extraction

When you upload an image to Cloudinary, by default the upload API response will report basic information about the uploaded image such as width, height, number of bytes, format, and more. Cloudinary also supports extracting additional information from the uploaded image: image metadata (including Exif, IPTC, XMP and GPS), color histogram, predominant colors, custom coordinates, pHash image fingerprint, ETag, and face coordinates.

You can tell Cloudinary to include additional information in its upload API response by including one or more of the following parameters while calling the upload API.

  • colors - Optional (Boolean, default: false). If true, include color information: predominant colors and histogram of 32 leading colors.
  • image_metadata - Optional (Boolean, default: false). If true, include IPTC, XMP and detailed Exif metadata of the uploaded image.
  • exif - Optional (Boolean, default: false). If true, include image metadata (e.g., camera details). Deprecated. Please use image_metadata instead.
  • faces - Optional (Boolean, default: false). If true, include a list of the coordinates of automatically detected faces.
  • phash - Optional (Boolean, default: false). If true, include the perceptual hash (pHash) of the uploaded image for similarity detection (see the blog post on how to automatically identify similar images using phash for more information.

In addition, the following information is also returned in the upload response:

  • etag - Used to determine whether two versions of an image are identical.
  • pages - The number of pages in the file: included in the response only if the uploaded file has multiple pages (e.g., PDF or animated GIF).
  • coordinates - Included in the response if face coordinates and/or custom coordinates are defined for the image.

The following example uploads an image and requests the pHash value, a color analysis and the image metadata:

Ruby:
Cloudinary::Uploader.upload("sample.jpg",
    :colors => true,
    :phash => true,
    :image_metadata => true)
PHP:
\Cloudinary\Uploader::upload("sample.jpg", array( 
    "colors" => TRUE,
    "phash" => TRUE,
    "image_metadata" => TRUE));
Python:
cloudinary.uploader.upload("sample.jpg", 
    colors = true,
    phash = true,
    image_metadata = true)
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { colors: true,
      phash: true,
      image_metadata: true }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap(
        "colors", true,
        "phash", true,
        "image_metadata", true));

The following is an example of a JSON response returned with the following additional information: image_metadata, colors and phash

{
  "public_id": "couple",
  "version": 1436702762,
  "signature": "1cc5524ae9acde77c458a434e32f6d26a8d4b55c",
  "width": 400,
  "height": 300,
  "format": "jpg",
  "resource_type": "image",
  "created_at": "2015-07-12T12:06:02Z",
  "tags": [],
  "bytes": 206960,
  "type": "upload",
  "etag": "9359a0f3ec878d32e06a456c4224b52b",
  "url": "http://res.cloudinary.com/demo/image/upload/v1436702762/couple.jpg",
  "secure_url": "https://res.cloudinary.com/demo/image/upload/v1436702762/couple.jpg",
  "image_metadata": {
    "PerspectiveHorizontal": "0",
    "RedHue": "0",
    "Exposure": "0.00",
    ...
    ...
    ...
    "ExposureTime": "1/320"
  },
  "colors": [
    ["#152E02", 7.9], ["#2E4F06", 6.3], ["#3A6604", 5.6], ["#EEF2F3", 5.2], ["#598504", 4.6], ["#0D1903", 4.6], ["#DCDFDB", 4.4], ["#7AA403", 3.9], ["#DBE98A", 3.8], ["#4C7208", 3.5], ["#8DAC30", 3.3], ["#6C9406", 3.2], ["#6E912F", 3.2], ["#B0C95F", 3.1], ["#89AF07", 3.1], ["#9E744E", 2.9], ["#CD9A6F", 2.8], ["#D8B395", 2.5], ["#719357", 2.4], ["#ACCDBC", 2.3], ["#8E6437", 2.3], ["#E2E0A0", 2.3], ["#2C4B16", 2.3], ["#656950", 2.1], ["#25370A", 2.0], ["#73A092", 1.9], ["#4E3721", 1.6], ["#A0AD9A", 1.6], ["#BBD258", 1.5], ["#5B602B", 1.3], ["#302B1D", 1.3], ["#9CA25C", 1.2]
  ], 
  "predominant": {
    "google": [
      ["yellow", 40.1],
      ["green", 24.6],
      ["brown", 13.4],
      ["black", 12.5],
      ["teal",  9.4]
    ]
  },
  "phash": "ebb822db6d10f1e",
  "coordinates": {
    "custom": [[80, 140, 220, 111]],
    "faces": [[98, 74, 61, 83], [139, 130, 52, 71]]    
  },
  "original_filename": "couple"
}

You can ask Cloudinary for semantic data either during the upload API call for newly uploaded images as shown above, or using our Admin API for previously uploaded images (see Cloudinary's Admin API documentation for more details).

See the blog post on API for extracting semantic image data - colors, faces, Exif data and more for more information on semantic data extraction.

Control access to images

When uploading images to Cloudinary, both the original images and their transformed versions are publicly available through a CDN, by default. You can use random Public IDs to make it harder to guess image URLs (Cloudinary's default behavior if no Public ID is specified), but you might still want further access control.

Private images

You can upload images as private to restrict access to the original image and only allow access to derived (transformed) versions of the image. The original image can be accessed only with a signed URL, but by default, all derived versions of the image are accessible. You can further restrict access to the derived images by activating the Strict Transformations mode. This mode also prevents access to the derived versions of the image, except for those that have been specifically enabled (e.g., with watermarks) that are then available for public delivery to your users (see the image manipulation and delivery documentation for more information). With Strict Transformations enabled you need to either eagerly generate all derived images, mark specific transformations as allowed or use signed URLs.

To upload an image as a private image, you set the type parameter to private (instead of the default upload) when uploading the image to Cloudinary. This holds true for all resources, including raw files and videos.

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :type => :private)
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("type" => "private"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    type = "private")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { type: "private" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("type", "private"));

An image that was uploaded as �private’ cannot be accessed publicly without a signed URL. For example, the following URL returns an error:

http://res.cloudinary.com/demo/image/private/sample.jpg

Note: You can make a private original image temporarily accessible, for example, to enable a customer to access a stock photo on your site after she purchases it. To do this, you need to deliver a time-limited and signed URL. You can do this directly using the API or you can use the private_download_url Utils method, which generates a time-limited, signed URL link to the original image, which you can then provide to relevant customers. For details, see Providing time-limited access to private images

Authenticated images

You can upload images as authenticated to even further restrict access to both the original image and to the derived (transformed) versions of the image. Authenticated images and their derived versions cannot be accessed without some form of authentication. For more information see delivering authenticated images.

To upload an image as an authenticated image, you set the type parameter to authenticated (instead of the default upload) when uploading the image to Cloudinary.

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :type => :authenticated)
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("type" => "authenticated"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    type = "authenticated")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { type: "authenticated" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("type", "authenticated"));

If an image was uploaded as �authenticated’, neither the image nor any of its derived images can be accessed without authentication. For example, the following URL returns an error:

http://res.cloudinary.com/demo/image/authenticated/sample.jpg

Access mode

The access_mode parameter allows a resource of type 'upload' to behave as if it's of type 'authenticated' while still using the default 'upload' type in delivery URLs. The image can later be made public by changing its access_mode via the Admin API, without having to update any image delivery URLs. Valid values for the access_mode parameter include public (default) and authenticated.

For example, to upload the 'sample' image and set its access_mode as authenticated:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :access_mode => :authenticated)
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("access_mode" => "authenticated"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    access_mode = "authenticated")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { access_mode: "authenticated" }, 
    function(error, result) {console.log(result); });
Java:
cloudinary.uploader().upload("sample.jpg", 
    ObjectUtils.asMap("access_mode", "authenticated"));

Update already uploaded images

The explicit API method is used to apply actions on already uploaded images. The most common usage of this method is to generate transformations for images that have already been uploaded. This is particularly useful when Strict Transformations are enabled for your account and you cannot create transformed images on the fly (for more information, see Control access to images). In order to generate these transformations, this method uses the eager parameter to define the list of transformations to create for the uploaded image of a specified Public ID (see the Image manipulation reference documentation for more details on possible transformation values). The eager parameter accepts either a single transformation or an array of transformations, where each transformation is represented by a hash of parameters to create for the uploaded resource.

Examples of other uses for the explicit method include:

  • Updating the meta data parameters stored with the image, such as custom_coordinates, face_coordinates, tags, etc.
  • Invalidating cached copies of the image on the CDN.
  • Applying one of Cloudinary's add-ons to the image (e.g., removing the background).

The explicit API method also requires specifying the type of the resource:: upload, private or authenticated. For example, the following method will explicitly generate two transformations for the already uploaded JPG private image named sample3:

  1. Scale to a width of 200 pixels.
  2. Crop to a width of 360 pixels and a height of 200 pixels with north gravity.
Ruby:
Cloudinary::Uploader.explicit("sample3", 
    :type => "private",
    :eager => [
     {:width => 200, :crop => :scale}, 
     {:width => 360, :height => 200, :crop => :crop, :gravity => :north }])
PHP:
\Cloudinary\Uploader::explicit("sample3", array(
    "type" => "private", 
    "eager" => array(
      array("width" => 200, "crop" => "scale"),
      array("width" => 360, "height" => 200, "crop" => "crop", "gravity" => "north"))));
Python:
cloudinary.uploader.explicit("sample3", 
    type = "private", 
    eager = [
      {"width": 200, "crop": "scale"},
      {"width": 360, "height": 200, "crop": "crop", "gravity": "north"}])
Node.js:
cloudinary.v2.uploader.explicit("sample3", 
    { type: "private",
      eager: [
      { width: 200, crop: "scale" }, 
      { width: 360, height: 200, crop: "crop", gravity: "north"} ] }, 
    function(error, result) {console.log(result); } );
Java:
cloudinary.uploader().explicit("sample3", ObjectUtils.asMap(
     "type", "private",
     "eager", Arrays.asList(
       new Transformation().width(200).crop("scale"),
       new Transformation().width(360).height(200).crop("crop").gravity("north"))));

Upload Presets

Upload presets enable you to centrally define a set of image upload options instead of specifying them in each upload call. You can define multiple upload presets, and apply different presets in different upload scenarios.

Upload presets can be defined in the Management Console or with the Admin API. From the console, you can also select one of your upload presets to be the Default upload preset. The settings in this preset are applied whenever no other preset is specified directly in an upload call. You can also separately select one of your presets as the Media library's upload preset. If specified, this preset overrides the Default upload preset for all images uploaded via the Media Library.

Some use-cases for using presets include:

  • Generating eager transformations for an uploaded image
  • Applying incoming transformations while uploading a file, for example to limit format types or file size before storing uploaded files in your Cloudinary account.
  • Using Cloudinary's add-ons without updating an existing mobile app or website application already in production.
  • Simplifying control and management of uploading images.

Presets are also used for special purposes to allow unsigned uploading directly from the browser and to define upload options to be used with the Auto Upload feature.

Each upload preset has a unique name. To apply an upload preset when uploading an image, specify the preset name as the value of the upload_preset parameter.

For example, uploading the image sample.jpg and specifying an upload preset named splice:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :upload_preset => "splice")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("upload_preset" => "splice"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    upload_preset = 'splice')
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { upload_preset: "splice" }, 
    function(error, result) {console.log(result) });
Java:
cloudinary.uploader().upload(new File("sample.jpg"),
    ObjectUtils.asMap("upload_preset", "splice"));

Creating images from text

Note: Cloudinary supports dynamic text overlays without predefining text images. See the documentation on Adding text captions and the blog post on How to overlay text on image easily, pixel perfect and with no CSS/HTML for more details.

You can use Cloudinary to dynamically generate an image of a given textual string using the text method of the API. For example, to create an image of the text string "Hello World":

Ruby:
Cloudinary::Uploader.text('Hello World')
PHP:
\Cloudinary\Uploader::text('Hello World');
Python:
cloudinary.uploader.text('Hello World')
Node.js:
cloudinary.v2.uploader.text('Hello World', 
    function(error, result) 
    {console.log(result) });
Java:
cloudinary.uploader().text("Hello World",
    ObjectUtils.emptyMap());

You can also optionally include various font, color and style parameters that can be specified to customize the look & feel of the text based image as follows:

  • public_id - The identifier that is used for accessing the generated image. If not specified, a unique identifier is generated by Cloudinary.
  • font_family - The name of the font family.
  • font_size - Font size in points. Default: 12.
  • font_color - Name or RGB representation of the font's color. For example: 'red', '#ff0000'. Default: 'black'.
  • font_weight - Whether to use a 'normal' or a 'bold' font. Default: 'normal'.
  • font_style - Whether to use a 'normal' or an 'italic' font. Default: 'normal'.
  • background - Name or RGB representation of the background color of the generated image. For example: 'red', '#ff0000'. Default: 'transparent'.
  • opacity - Text opacity value between 0 (invisible) and 100. Default: 100.
  • text_decoration - Set to 'underline' to define a line below the text. Default: 'none'.

For example, to create an image of the text string "Sample Name" in 12 point, black, Arial font with 90% opacity, and the Public ID of "dark_name":

Ruby:
Cloudinary::Uploader.text("Sample Name",
    :public_id => "dark_name",
    :font_family => "Arial", 
    :font_size => 12,
    :font_color => "black",
    :opacity => 90)
PHP:
\Cloudinary\Uploader::text("Sample Name",
    array(
        "public_id" => "dark_name",
        "font_family" => "Arial", 
        "font_size" => 12,
        "font_color" => "black", 
        "opacity" => 90));
Python:
cloudinary.uploader.text("Sample Name",
    ublic_id = 'dark_name',
    font_family = 'Arial', 
    font_size = 12,
    font_color = 'black',
    opacity = 90)
Node.js:
cloudinary.v2.uploader.text("Sample Name",
    { public_id: "dark_name",
      font_family: "Arial", 
      font_size: 12,
      font_color: "black", 
      opacity: 90 }, 
    function(error,result) { console.log(result) });
Java:
cloudinary.uploader.text("Sample Name",
    ObjectUtils.asMap(
        "public_id", "dark_name",
        "font_family", "Arial",
        "font_size", 12,
        "font_color", "black",
        "opacity", "90"));

The resulting image will also include all the styling information stored as metadata, which means the resulting image can be referred to as a "text style" base for creating text overlays on the fly. See the documentation on Text style images for more information.

The API call returns a JSON response including the URLs for accessing the generated image through a CDN, the assigned Public ID and the current version of the resource.

For example:

{
 url: 'http://res.cloudinary.com/demo/image/text/v1337611986/12355d88728f5dc6886d96847c0c7ced.png',
 secure_url: 'https://res.cloudinary.com/demo/image/text/v1337611986/12355d88728f5dc6886d96847c0c7ced.png',
 public_id: '12355d88728f5dc6886d96847c0c7ced',
 version: '1337611986',
 width: 124, 
 height: 15
}

Image administration

Images can be administered through Cloudinary's API (or the Media Library web interface) which allows you to perform the following actions on an uploaded image file:

Note: The Cloudinary Admin API also has useful methods for administering and organizing your image files, such as listing all uploaded images, listing tags, finding all images that share a given tag, updating transformations, bulk deleting, etc. See the documentation on the Cloudinary Admin API for more information.

Deleting images

Deleted images are immediately and permanently deleted from your cloud storage with the destroy method. However, images and transformed images already downloaded by visitors to your website might still be accessible through cached copies on the CDN. This method deletes a single resource at a time: to delete multiple images see the Admin API Delete resources method.

You can set the invalidate parameter to true while deleting an image in order to also invalidate the copies of the image on the CDN. Note that it usually takes a few minutes (although it might take up to an hour) for the invalidation to fully propagate through the CDN. There are also a number of other important considerations when using the invalidate functionality.

For example, deleting an image with the Public ID of "sample":

Ruby:
Cloudinary::Uploader.destroy('sample')
PHP:
\Cloudinary\Uploader::destroy('sample');
Python:
cloudinary.uploader.destroy('sample')
Node.js:
cloudinary.v2.uploader.destroy('sample', 
    function(error, result) {console.log(result) });
Java:
cloudinary.uploader().destroy('sample',
    ObjectUtils.emptyMap());

Renaming images

Renamed images are immediately and permanently updated in your cloud storage with the rename method of the API. Any existing URLs of renamed images and their associated derived images are no longer valid, but images and transformed images already downloaded by visitors of your website might still be accessible for a certain period of time through cached copies on the CDN.

You can set the invalidate parameter to true while renaming an image in order to also invalidate the cached copies of the image on the CDN. Note that it usually takes a few minutes (although it might take up to an hour) for the invalidation to fully propagate through the CDN. There are also a number of other important considerations when using the invalidate functionality.

For example, renaming an image with the Public ID of old_name to new_name:

Ruby:
Cloudinary::Uploader.rename('old_name', 'new_name')
PHP:
\Cloudinary\Uploader::rename('old_name', 'new_name');
Python:
cloudinary.uploader.rename('old_name', 'new_name')
Node.js:
cloudinary.v2.uploader.rename('old_name', 'new_name', 
    function(error, result) { console.log(result) })
Java:
cloudinary.uploader().rename("old_name", "new_name", 
    ObjectUtils.emptyMap());

You can also add one of the following optional parameters:

  • overwrite - (Boolean) Whether to overwrite an existing image with the target Public ID. Default: false.
  • invalidate - (Boolean) Whether to invalidate cached copies of the image on the CDN. Default: false.

Invalidating cached images on the CDN

Even after you delete, rename, or overwrite an image in your Cloudinary storage, the old cached image can remain on the CDN servers for up to 30 days.

To prevent users from accessing the old image, you can send an invalidation request instructing the CDN to remove cached copies of the old image, so that the next request for the image will pull the newest copy from your Cloudinary storage, or will return an error if the image no longer exists.

Important: It can take from a few minutes up to an hour for the invalidation to fully propagate through the CDN. To bypass the CDN cached version and force immediate delivery of the newest image, include versions in your delivery URLs.

You can send an invalidation request by setting the invalidate parameter to true in relevant methods of the Upload API. From within the Media Library, an invalidate request is automatically included whenever you delete, rename, or overwrite images. You may also be able to use relevant Admin API methods to invalidate resources if support for bulk invalidations has been added to your account (not supported by default).

The images that will actually be invalidated during an invalidate request depend on the value set for the global Invalidate versioned URLs option in your account’s upload settings and whether the public ID of a particular URL is organized in a folder structure. The table below summarizes these considerations.

Invalidate versioned URLs Disabled (default) Enabled
Images not in folders Only URLs without a version are invalidated. For example:

https://res.cloudinary.com/demo/image/upload/sample.jpg
Only URLs with the most recent version are invalidated. For example:

https://res.cloudinary.com/demo/image/upload/v14858684/sample.jpg
Images in folders Only URLs delivered with the /v1/ component are invalidated. For example:

https://res.cloudinary.com/demo/image/upload/v1/folder1/folder2/sample.jpg
Only URLs with the most recent version are invalidated. For example:

https://res.cloudinary.com/demo/image/upload/v14858684/folder1/folder2/sample.jpg

Note: If you need to invalidate images with a folder structure that were delivered without the /v1/ component, or if you need to invalidate signed URLs (with or without versions), submit a service request.

Tagging images

Tags are used to categorize and organize your images, and can also be used to bulk delete images, create sprites, ZIP files, JSON lists, generate PDFs and animated GIFs. Each image can be assigned one or more tags, which is a short name that you can dynamically use (no need to predefine tags). You can assign tags to images while uploading them by also specifying the tags parameter in the upload method.

For example, uploading the image sample.jpg and adding the tag animal to the image:

Ruby:
Cloudinary::Uploader.upload("sample.jpg", 
    :tags => "animal")
PHP:
\Cloudinary\Uploader::upload("sample.jpg", 
    array("tags" => "animal"));
Python:
cloudinary.uploader.upload("sample.jpg", 
    tags = "animal")
Node.js:
cloudinary.v2.uploader.upload("sample.jpg", 
    { tags: "animal" }, 
    function(error, result) {console.log(result) });
Java:
cloudinary.uploader().upload(new File("sample.jpg"),
    ObjectUtils.asMap("tags", "animal"));

You can also use our API or Management Console for adding, removing or changing tags assigned to images. Cloudinary's SDKs allow you to add tags to previously uploaded images with the add_tag API method. This method accepts 2 parameters (use an array for multiple values): the tag(s) to add and the Public ID(s) of the image(s) to be tagged. For example, adding the tag "animal" to the images with the Public IDs of "dog" and "lion":

Ruby:
Cloudinary::Uploader.add_tag('animal', 
    ['dog', 'lion'])
PHP:
\Cloudinary\Uploader::add_tag('animal', 
    array('dog', 'lion'));
Python:
cloudinary.uploader.add_tag('animal', 
    ['dog', 'lion'])
Node.js:
cloudinary.v2.uploader.add_tag('animal', 
    [ 'dog', 'lion' ],
    function(error, result) { console.log(result) });
Java:
cloudinary.uploader().addTag("animal",
    ["dog", "lion"], 
    ObjectUtils.emptyMap());

Assigning tags to images allows you to create group actions on images that share the same tag. For example, using the resources_by_tag method of the Admin API to list all images that share the tag "animal":

Ruby:
Cloudinary::Api.resources_by_tag("animal")
PHP:
$api->resources_by_tag("animal");
Python:
cloudinary.api.resources_by_tag("animal")
Node.js:
cloudinary.api.resources_by_tag("animal", 
    function(error, result) {console.log(result) });
Java:
api.resourcesByTag("animal", 
    ObjectUtils.emptyMap());

Uploading with a direct call to the API

Cloudinary's client libraries (SDKs) wrap the Upload API and greatly simplify using the API methods (see the Upload API reference documentation for more information on all the Upload API's methods). Nevertheless, if you wish to upload files with a direct call to the API from within your own custom code you can send an HTTPS POST request to the following Cloudinary URL:

https://api.cloudinary.com/v1_1/<cloud name>/<resource_type>/upload

Where:

  • cloud name is the name of your Cloudinary account.
  • resource_type is the type of file to upload. Valid values: image, raw, video and auto to automatically detect the file type.

For example, to upload an image file to the Cloudinary 'demo' account, send an HTTPS POST request to the following URL:

https://api.cloudinary.com/v1_1/demo/image/upload

The contents of the POST request you send to Cloudinary depends on whether or not you are making an authenticated request (see the documentation on Unsigned uploads for more information on unauthenticated requests).

Required parameters for authenticated requests:

  • file - The file to upload. Can be the actual data (byte array buffer), the Data URI (Base64 encoded), a remote FTP, HTTP or HTTPS URL of an existing file, or an S3 URL (of a whitelisted bucket).
  • api_key - The unique API Key of your Cloudinary account.
  • timestamp - Unix time in seconds of the current time (e.g., 1315060076).
  • signature - A signature of all request parameters including the 'timestamp' parameter but excluding the 'api_key' and 'file' parameters, based on the API Secret of your Cloudinary account. The signature is valid for 1 hour. See Creating API authentication signatures for more details.

Required parameters for unauthenticated requests:

  • file - The file to upload. Can be the actual data (byte array buffer), the Data URI (Base64 encoded), a remote FTP, HTTP or HTTPS URL of an existing file, or an S3 URL (of a whitelisted bucket).
  • upload_preset - The name of an unsigned upload preset that you defined for unsigned uploading to your Cloudinary account.

Optional parameters:

See the Upload method of the API for all parameters available for uploading images. Note that unauthenticated requests are restricted to the following directly allowed parameters: public_id, folder, callback, tags, context, face_coordinates and custom_coordinates.

Error handling

Once the POST request is received and processed by Cloudinary, the Upload API returns the status of requests using one of the following HTTP status codes:

  • 200 - OK. Successful.
  • 400 - Bad request. Invalid request parameters.
  • 401 - Authorization required.
  • 403 - Not allowed.
  • 404 - Not found.
  • 420 - Rate limited.
  • 500 - Internal error. Contact support.

In the case of wrong usage of the API or an error, Cloudinary's response is returned with a non-OK (not 200) HTTP Status code and a body with the following JSON format:

{ error: { message: "Something went wrong" } }

Creating API authentication signatures

To manually authenticate your POST request, create a signature based on the parameters you use in the request. The signature is a hexadecimal message digest (hash value) created with the SHA-1 (Secure Hash Algorithm 1) cryptographic function as follows:

  1. Create a string with the parameters used in the POST request to Cloudinary:

    • All parameters should be included except the file, type, and resource_typeparameters, and the api_key.
    • Make sure to include the timestamp.
    • Sort the parameters by their names in alphabetical order.
    • Separate the parameter names from their values with an = and join the parameter/value pairs together with an &.
  2. Append your API secret to the end of the string.

  3. Create a hexadecimal message digest (hash value) of the string using the SHA-1 function.

For example, if your API secret is 'abcd', your API key is '1234', the Unix time now is 1315060510 and you are posting a request to upload a file from 'http://www.example.com/sample.jpg' and set its Public ID as 'sample_image':

  • Parameters to sign:
    • timestamp: 1315060510
    • public_id: "sample_image"
  • Serialized sorted parameters in a single string:
    • "public_id=sample_image&timestamp=1315060510"
  • String including the API secret that is used to create the SHA-1 signature:
    • "public_id=sample_image&timestamp=1315060510abcd"
  • SHA-1 hexadecimal result:
    • "b4ad47fb4e25c7bf5f92a20089f9db59bc302313"

The final request parameters for the upload POST request:

  • timestamp: 1315060510
  • public_id: "sample_image"
  • api_key: "1234"
  • file: "http://www.example.com/sample.jpg"
  • signature: "b4ad47fb4e25c7bf5f92a20089f9db59bc302313"

See the Image upload API reference for a list of API methods, parameters, and response samples.