Programmable Media

Uploading assets

Last updated: Nov-21-2023

Using Cloudinary's upload capabilities, you can upload media assets in bulk with a variety of options for customizing how they will be uploaded, including naming, whether to apply manually specified or automatically generated tags and metadata, whether to apply incoming transformations or other AI-based analysis of the uploaded assets, and much more.

When you upload to Cloudinary, your asset is not only stored, but Cloudinary also automatically analyzes and saves important data about each asset, such as format, size, resolution, prominent colors, etc. This data is also automatically indexed to enable searching on those attributes.

Cloudinary provides a secure and comprehensive API for easily uploading media files from server-side code, directly from the browser or from a mobile application. This API uses HTTPS over a secure protocol, and by default, the requests are authenticated with a signature. When needed, you can also use the API to perform unsigned uploads, but with a limited set of available upload parameters as a security precaution.

New to Cloudinary?

This guide provides an in-depth overview of Cloudinary's Upload API capabilities. To get started with the basics of uploading (and more) in 5 minutes or less, we recommend you first run through one of our backend SDK quickstarts.

Each quick start gives you the code to configure your SDK, run your first upload, and then perform a few other common Cloudinary operations, all using your favorite programming language or framework.

Quick example

The following code uploads the dog.jpg image, sets the public_id as my_dog, overwrites the existing image if one with that public_id already exists, and requests faces analysis on the image.

When the upload is complete, a JSON response is returned with details about the uploaded media asset, including the requested faces analysis.

Upload overview

There are various ways to upload your resources to your Cloudinary account. Cloudinary supports making both authenticated requests that require a signature generated on your backend, and unauthenticated requests with a restricted set of supported parameters.

The following table summarizes the main options to upload assets and some considerations to take into account for each of them:

Option Description Considerations
Cloudinary backend SDKs The Cloudinary backend SDKs wrap the upload API, including taking care of the upload itself, the signature authentication and the response verification. ✅ Significantly simplifies the upload code compared to directly calling the REST API
✅ Automatically generates an authentication signature and validates the response
✅ Enables you to code in your chosen language
✅ Provides built-in support for uploading large files with chunked uploading
Upload widget An interactive, feature-rich interface you can embed in your website or application to allow your users to upload assets directly to Cloudinary. ✅ No need to develop an in-house interactive file upload solution
✅ Simple to integrate
✅ Can be used for unauthenticated client-side uploads
✅ Enables uploading directly from a variety of social media & stock photo accounts
'upload' endpoint of the REST API The upload endpoint of the Cloudinary API supports making both authenticated requests that require a signature be generated on your backend, and unauthenticated requests with a restricted set of supported parameters. ✅ Can be used for unauthenticated client-side requests
✅ Useful when coding in a language not covered by Cloudinary's SDKs
💡 Requires manually coding the upload and validating the response
💡 Requires a function on your backend to generate the signature for authenticated calls
Direct upload from a browser The Cloudinary Backend SDKs can also be used to automatically add a file input field to your form that uploads files directly to Cloudinary, bypassing your own servers. ✅ Uploads directly to your account, bypassing your own servers
💡 Requires additional setup and configuration
💡 Requires the Cloudinary jQuery plugin
The Cloudinary CLI The Cloudinary CLI (Command Line Interface) enables you to interact with Cloudinary through the command line and provides additional features and helper commands. ✅ Simple to use
✅ Useful for quickly uploading assets without setting up a formal coding environment
✅ Useful for experimenting with upload parameters and behavior
✅ Upload-specific helper functions (e.g., sync) not directly provided via the other upload options
Lazy migration Cloudinary's lazy migration with the auto-upload feature enables you to migrate files on demand from a remote location, where each asset is automatically uploaded to Cloudinary the first time the delivery URL for that asset is requested. ✅ Simple to implement
✅ Only upload the assets you really need
💡 Not suitable if there's a deadline when the remote content will be unavailable
Media Explorer The Media Explorer page in the Cloudinary Console lets you upload assets to your account using drag and drop or the built-in upload widget. ✅ Simple to use
✅ Useful for quickly uploading assets without dealing with code
✅ Useful for experimenting with upload preset behavior
💡 Less suitable as a primary means of uploading assets compared to programmatic solutions
Integrations Cloudinary has developed and certified integrations with many leading eCommerce, CMS and PIM platforms. ✅ Enables platform users to upload to Cloudinary from directly within the platform UI
💡 Requires initial set up and configuration by a platform administrator
💡 Less suitable as a primary means of uploading assets compared to programmatic solutions
Media Library widget The Media Library widget enables embedding all the Cloudinary Media Library UI capabilities, including upload, into another application's UI. ✅ Useful for implementing your own Cloudinary integration
💡 Less suitable as a primary means of uploading assets at scale compared to programmatic solutions

Tips:
  • MediaFlows, Cloudinary’s drag-and-drop workflow builder for image and video (currently in beta), offers the option to automate image upload with a low-code implementation. See MediaFlow’s documentation on media upload here.
  • Usage limits for uploading, transforming and delivering files depend on your Cloudinary plan. For details, check the Account tab in your Cloudinary Console Settings.

Uploading with a direct call to the REST API

You can upload assets programmatically either by using authenticated uploads that include a signature, or using unauthenticated uploads without a signature but with certain restrictions for security reasons.

The upload API method enables you to upload files with a direct call to Cloudinary by sending 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 product environment.
  • 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' product environment, 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 or an unauthenticated request.

Tips
  • Cloudinary's backend SDKs wrap the Upload API and greatly simplify using the API methods.
  • Use the auto-upload feature for lazy migration of all your assets from a remote location to Cloudinary with minimal effort on your side.
  • Enterprise customers can set up their account to use an EU or AP data center with the endpoints becoming api-eu.cloudinary.com or api-ap.cloudinary.com respectively.

Authenticated requests

Authenticated upload requests are performed over HTTPS using a secure protocol and include an authentication signature that is generated based on your product environment's cloud_name, api_key and api_secret parameters. This signature should be generated on your backend, as you should never expose your api_secret in client-side code.

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 a private storage bucket (S3 or Google Storage) URL of a whitelisted bucket. See File source options for more details.
  • api_key - The unique API Key of your Cloudinary product environment.
  • 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', 'resource_type', 'cloud_name' and 'file' parameters, based on your product environment's API secret. The signature is valid for 1 hour. See Generating authentication signatures for more details.

Note
There are also a large number of Optional upload parameters that can be added to the upload method.

For example, to upload the sample.jpg file to the Cloudinary demo product environment:

Code explorer: Upload multiple files using a form (signed)

To perform an authenticated request, you need to call a server-side component to generate a signature using your API secret, which should never be exposed on the client side. Having obtained the signature and timestamp from your server, you can use similar code to the unauthenticated example, just appending your API key, timestamp and signature to formData. See signed-uploads/public/js/uploadclientform.js in the following example.

Run the app
  1. Click Remix to Edit
  2. Enter your Cloudinary credentials in signed-uploads/public/js/config.js
  3. Click View App
  4. Click the Upload Files Using a Form link

This code is also available in GitHub.

Unauthenticated requests

Unauthenticated upload requests are an option for performing upload without the need to generate an authentication signature on your backend. 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 product environment from the Upload Settings page. Enabling unsigned uploading automatically creates an upload preset with a unique name, which explicitly allows uploading of assets without authentication. You can use the preset to define which upload options you want to apply to all assets that are uploaded with that preset specified. You can rename or modify the preset options at any point in time or create additional upload presets with different parameters set for different upload use cases. You can also manage upload presets programmatically using the Admin API. For more information on upload presets, see the upload preset guide and the upload_presets method of the Admin API.

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 a private storage bucket (S3 or Google Storage) URL of a whitelisted bucket. See File source options for more details.
  • upload_preset - The name of an unsigned upload preset that you defined for unsigned uploading.

For example, to upload the sample.jpg file to the Cloudinary demo product environment with the unsigned_1 upload preset:

Note
For security reasons, only this restricted set of parameters can be used in an unsigned upload request. However, most upload parameters can be defined as part of your unsigned upload preset.

Code explorer: Upload multiple files using a form (unsigned)

This example shows one way to upload selected local files to Cloudinary using a direct call to the REST API. The call is made via an unauthenticated POST request as this is purely client-side code, so an unsigned upload preset (docs_upload_example_us_preset) is used.

This code is also available in GitHub.

Note
For security reasons, the upload preset used in this example sets the access control mode of the uploaded assets to restricted, so the URLs returned in the response will return 404 errors.

Code explorer: Chunked asset upload from the client side

Tip
The Cloudinary SDKs include an upload_large method for chunked asset uploading.

Here's an example of uploading large files using pure client-side code, in this case React. The code explorer makes use of the byte Content-Range entity-header HTTP specification to send the file in multiple calls.

Run the app

To try this out you'll need an unsigned upload preset configured for your product environment.

Set your cloud name and the name of the upload preset in CldCustUploadLgRestApi.js.

This code is also available in GitHub.

Uploading with Cloudinary backend SDKs

Cloudinary's backend SDKs wrap the Upload API and greatly simplify using the API methods, including automatically generating the authentication signature based on the product environment credentials provided in your SDK configuration.

The Cloudinary upload method performs an authenticated upload API call over HTTPS using the following syntax:

Note
There are also a large number of Optional upload parameters that can be added to the upload method.

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

Uploading is performed synchronously, and once finished, the uploaded asset is immediately available for transformation and delivery.

For more information on Uploading using our backend SDKs, visit the Upload page of the relevant backend SDK guide.

Tip
You can use the auto-upload feature for lazy migration of all your assets from a remote location to Cloudinary with minimal effort on your side.

Programmatic upload with the Node.js SDK video tutorial

Watch this video on how to quickly upload images, videos and other media files to Cloudinary using Cloudinary's Node.js SDK.


Unsigned upload

The Cloudinary backend SDKs also support unsigned upload methods as an option for performing unauthenticated requests without the need to generate an authentication signature on your backend. 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 product environment from the Upload Settings page. Enabling unsigned uploading automatically creates an upload preset with a unique name, which explicitly allows uploading of assets without authentication. You can use the preset to define which upload options you want to apply to all assets that are uploaded with that preset specified. You can rename or modify the preset options at any point in time or create additional upload presets with different parameters set for different upload use cases. You can also manage upload presets programmatically using the Admin API. For more information on upload presets, see the upload preset guide and the upload_presets method of the Admin API.

To perform an unsigned upload, 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 with the unsigned_1 upload preset:

Note
For security reasons, only this restricted set of parameters can be used in an unsigned upload request. However, most upload parameters can be defined as part of your unsigned upload preset.

Chunked asset upload

To support the upload of large files, the Cloudinary SDKs include a method which offers a degree of tolerance for network issues. The upload_large method uploads a large file to the cloud in chunks, and is required for any files that are larger than 100 MB. This is often relevant for video files, as they tend to have larger files sizes.

By default, when using the upload_large method, files are uploaded as raw files if the resource_type parameter is not specified. For more details about the resource_type option, see Asset types.

Note
Any file larger than 20 GB also needs to be uploaded asynchronously by adding the async parameter set to true. If you need to upload very large files you can contact support to increase your upload limit up to 100 GB. You can see your current usage limits in your Console Account Settings.

For example, uploading a large video file named my_large_video.mp4:

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

Note
There are multiple responses to a chunked upload: one after each chunk that only includes basic information plus the done : false parameter, and a full upload response that is returned after the final chunk is uploaded with done: true included in the response.

Client-side uploading

The upload samples shown in the Cloudinary backend SDK sections above upload files to Cloudinary via your server-side code. For example, if you have a web form that allows your users to upload media files, the file data is first sent to your server and only then uploaded to Cloudinary.

In some cases, you may prefer to upload user-generated content directly from the browser or your mobile app to Cloudinary instead of going through your servers. This 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.

Client-side uploading can be implemented as follows:

  • A direct call to the API for a pure client-side app with no backend, where you want to design your own custom interface for uploading files.
  • Cloudinary's Upload widget is an interactive, feature rich, simple to integrate method to upload files directly to Cloudinary, eliminating the hassle of developing an in-house interactive file upload solution.
  • Directly upload from a browser via a Cloudinary backend SDK and Cloudinary's jQuery plugin, while bypassing your own servers.

Upload widget

Cloudinary's upload widget is an interactive, feature-rich, simple to integrate method to allow your users to upload media files directly to Cloudinary. The widget eliminates the hassle of developing an in-house interactive file 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 files, a remote file (URL) or just snapping a photo directly from the computer or mobile device's camera. The widget supports 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 main screen

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. First, include the remote JavaScript file of the upload widget:

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

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

Direct uploading from the browser via a backend SDK

This section gives details on how to use one of Cloudinary's Backend SDKs to upload a file directly to Cloudinary and bypass your own servers. This 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 the relevant SDK integration guide.

Activate signed client-side asset 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):

When uploading is completed, the identifier of the uploaded asset 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 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">)

Upload multiple assets

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:

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 file, 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 asset and you can display a cloud-generated thumbnail of the uploaded assets 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.

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 documentation of jQuery-File-Upload.

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

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

Deleting client-side uploaded assets

The Cloudinary jQuery library supports using a delete token to delete assets on the client side for a limited time of 10 minutes after being uploaded. After 10 minutes have passed, the image cannot be deleted from the client side, only via the Destroy method of the Upload API or using the delete_resources method of 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. This parameter is not supported when using unsigned uploads (although it can be set within the upload preset for the unsigned upload).

For example:

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

Alternatively, you can access the delete_by_token endpoint directly with a POST request. For example:

Required upload parameters

The only required parameter is for specifying the source of the file to upload. Cloudinary supports uploading media files from various sources, including from a local path, a remote URL, a private storage URL (S3 or Google Cloud storage), a data stream, a Base64 data URI, or an FTP URL.

Upload from a local path

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

Upload from a remote URL

If your assets are already publicly available online, you can specify their remote HTTP or HTTPS URLs instead of uploading the actual file or file data. In this case, Cloudinary will retrieve the file from its remote URL and upload it directly to Cloudinary. This option allows for a much faster migration of your existing media files. For example:

Upload from a private storage URL (Amazon S3 or Google Cloud)

If you have existing media files in a private storage (Amazon S3 or Google Cloud storage) bucket, you can upload files from a storage bucket URL.

Notes
  • You can also use your private storage bucket for lazy uploading using the auto-upload mapping functionality or for primary and backup storage.
  • When using your own backup storage, the backup location should not be touched or modified in any way. Additionally, no archiving policy should be enforced on that location (such as an archive policy to a glacier on S3 buckets).

To enable this option, your storage bucket must be whitelisted. This requires the following steps:

  1. Add an empty file to your bucket with your cloud name as the filename, under the following folder structure: .wellknown/cloudinary/<your_cloud_name>

    • By adding this file, you indicate that you have access to this bucket and that you permit Cloudinary to upload from this bucket to the product environment with the specified cloud name.
    • If you want this bucket to be whitelisted for more than one Cloudinary product environment, you can add an appropriately named file for each cloud name.
  2. Provide Cloudinary with read access to your bucket:
    - How to set read access on a private Amazon S3 bucket
    - How to set read access on a Google Storage bucket

After your storage bucket is whitelisted, you can pass the Amazon S3 (s3://my-bucket/...) or Google Storage (gs://mybucket/...) URL in your upload method.

S3 example:

Google Cloud example:

How to set read access on a private Amazon S3 bucket

  1. In Amazon's AWS S3 Console, select the relevant bucket.
  2. In the Bucket Policy properties, paste the following policy text.
    Keep the Version value as shown below, but change BUCKETNAME to the name of your bucket.
    If a policy already exists, append this text to the existing policy:

Note
Amazon S3 bucket names containing a . character are not supported for this purpose.

How to set read access on a Google Storage bucket
  1. In your GCP console, go to your Google bucket's main page.
  2. Select to edit bucket permissions.
  3. Add service@cloudinary-gcs-production.iam.gserviceaccount.com as a member and give it the Storage Object Viewer role.

Upload data stream

You can upload an actual data stream (byte array buffer):

Note
The Node.js SDK uses the dedicated upload_stream method.

Upload via a Base64 data URI

You can upload a file by specifying the Data URI of the file in Base64 encoding (no larger than 60 MB). For example:

Upload from an FTP URL

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

Optional upload parameters

The upload method supports a large number of optional parameters, from naming and storage options, to adding tags and metadata, as well as requesting analysis or add-ons, or even transforming the asset before storage. This section provides additional information on some of the most commonly used optional parameters:

Tip
For a full listing of ALL the possible optional parameters (options = {}) available for the upload method, see the Upload API reference.

Public ID

Every asset 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 Explorer 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 looks something like this: 8jsb1xofxdqamu2rzwt9q. The resulting delivery URL for such an asset would be something like:

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

You can set the public_id parameter when you upload an asset, which is useful when you want your delivery URLs to be more readable and SEO-friendly. For example:

This section contains the following topics:

Public ID naming preferences

To tell Cloudinary to use the original name of the uploaded file as its public ID, include the use_filename parameter and set it to true. 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. By also including the unique_filename parameter and setting it to false, you can 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 with the filename, sample_file.jpg and ensure that the Public ID of the asset is set to sample_file:

Notes
  • The public ID value for image and video asset types should not include the file extension. If you include a . character in a public ID, it's simply another character in the public ID value itself. The format (extension) of a media asset is appended to the public_id when it is delivered. For example, if you specify myname.mp4 as the public_id, then the video would be delivered as myname.mp4.mp4.
  • For raw asset types only, the file extension should be specified as part of the public_id.
  • Public IDs can be up to 255 characters, including non-English characters, periods (.), forward slashes (/), underscores (_), hyphens (-).
  • Public ID values cannot begin or end with a space or forward slash (/). Additionally, they cannot include the following characters: ? & # \ % < > +

Including a path in the Public ID

The Public ID value can include path elements (slashes) for more structured delivery URLs and to assist with SEO. For example:

This can also be done by splitting the Public ID into 2 parts, specifying only the last element of the public ID in the public_id parameter, and specifying the public ID path in the folder parameter. Using the same example as above, but this time with the folder parameter:

Notes
  • You cannot use v followed by numeric characters as the name of a path element in your public ID.
  • You cannot use /images/ or /videos/ as a path element in your public ID. Those names are reserved for use with dynamic SEO suffixes.
  • It's recommended to avoid using public ID path names starting with 1-3 characters followed by an underscore, such as my_path. By default, Cloudinary assumes that URL components following that pattern represent a Cloudinary transformation component. If the first path element of a public_id does follow that pattern, then when delivering assets from that path, you must separate the last transformation component from the path element with a version component. For example:

    https://res.cloudinary.com/my_cloud/image/upload/t_transf1/t_transf2/v1/my_path/sample.jpg
  • For details on delivering Public IDs in a path structure with or without versions, see Asset versions.
  • The effect on the Media Explorer of including path elements in public IDs depends on whether your product environment is using fixed folder mode or dynamic folder mode.
    • If your product environment is using fixed folder mode (most accounts and product environments created before September 2022 are using this mode), then including slashes in a public ID will also create folders in the same structure in the Media Explorer. If an asset is moved to a different folder in the Media Explorer, that results in a change to the asset's public ID.
    • If Dynamic folders mode is enabled on your product environment, slashes in a public ID do not impact how the asset is organized in the Media Explorer. Additionally, if in this mode, you should use the new asset_folder parameter instead of the folder parameter mentioned above to set the Media Explorer folder. Whether or not you define an asset folder for purposes of organizing assets in the Media Explorer, if you also want your public_id to include slashes, make sure to use one of the options available in that mode to set the public ID path.
    • If your product environment is using dynamic folder mode, you'll see a Dynamic Folders indication at the top of the Media Library Preferences in the console, and the response of a Get details of a resource method will include display_name and asset_folder response keys.
    • For more details on dynamic folders mode, see Dynamic folders - New Upload API parameters.

Asset types

Cloudinary supports many different file formats, which are categorized into three different asset types (resource_type in the API):

This section contains the following topics:

Passing the resource_type parameter to your upload call

  • When uploading using the REST API, the resource_type is part of your upload endpoint.
  • When uploading using a backend SDK, image is the default resource_type. When uploading video or raw file types, you must pass the resource_type option either with the value auto or with the relevant specific asset type.
  • When using direct image uploading from the browser, resource type is set to auto by default.
  • Uploading a password-protected PDF as an image asset is not supported. If necessary, you can upload a password-protected PDF by setting the resource_type to raw in the upload command. However, keep in mind that like any other raw file, you can deliver a raw PDF as is, but PDF transformations are not supported for raw assets.

Note that for simplicity, many of the examples in this guide demonstrate uploading an image file. If you use these code examples as the basis for your own video or raw file uploads, don't forget to add the resource_type option.

The 'auto' resource_type

The upload method also supports supplying auto as a value for the resource_type parameter. When you send this value, Cloudinary automatically detects the asset type of the uploaded file and automatically sets the relevant resource_type value for the stored asset.

For example:

The auto value is especially useful when you don't know what type of files your users will upload, or if you are uploading multiple files of different asset types with the same settings. When using auto as the resource_type along with other upload options, only the upload options relevant to a particular asset type are applied. Any options that work only with a different asset type are silently ignored.

Uploading videos

Uploading videos generally works the same and supports the same options as uploading images. However, when uploading videos, keep the following guidelines in mind:

  • The default value for the upload method resource_type parameter in SDKs is image, so you must set the resource_type parameter when uploading videos. You can set the resource_type parameter to auto to instruct Cloudinary to automatically detect the asset type, or you can set the parameter to video if you know in advance that you are uploading a video file.
  • By default, uploading is performed synchronously, and once finished, the uploaded video is immediately available for transformations and delivery. For videos larger than 100 MB, you will need to use chunked uploading.
  • There are also file-size limits for transforming larger videos on the fly. The exact limits depend on your account plan. Therefore, it's best practice to generate your video transformations eagerly on upload.

Here's a simple video upload example:

Audio files (such as MP3s) can also be uploaded as a video resource. Audio files are treated as video files without a visual element and thus are uploaded in the same way as videos, using video as the resource_type. For example, uploading a local audio file named audio_sample.mp3:

Tip
The Cloudinary Video Player provides a feature-rich and customizable interface to present your uploaded videos to your users and allows you to make use of functionality such as adaptive bitrate streaming and much more.

Uploading 3D models

Cloudinary supports 3D models in various formats. Where the format requires a set of files (for example, textures or other images used in the model), you should zip the entire folder and upload the single ZIP file to Cloudinary.

In order to use 3D models in the Product Gallery and perform transformations on them, the 3D model needs to be uploaded as an image asset type to Cloudinary.

ZIP files are normally uploaded as raw files if the asset type is not specified. However, Cloudinary is able to detect some 3D models and upload them as image types, which is especially useful if uploading manually from within your Media Explorer.

If you are uploading a 3D model programmatically, you can explicitly set resource_type to image. For example, to upload the 3D model archived in the sample_3D.zip file:

Uploading non-media files as raw files

Any file that is not an image or video file is treated as a 'raw' file. Raw files are stored as-is when uploaded to Cloudinary. No transformations on uploaded raw files are available. However, you can deliver your raw assets through a dynamic CDN URL in the same way you deliver image and video assets.

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

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

Converting raw files

The raw_convert upload parameter enables you to perform certain asynchronous operations on uploaded files. Depending on the option specified for this parameter, you can either convert certain raw files to other formats or generate related raw files that can be used in conjunction with the image or video file you uploaded.

For example:

  • Specify aspose as the value for your raw_convert parameter when uploading an Office document to instruct the Aspose Document Conversion add-on to generate a PDF image file from your raw office document.
  • Specify google_speech when uploading a video to instruct the Google AI Video Transcription add-on to generate an automatic transcript raw file from your uploaded video.
  • Specify extract_text when uploading a PDF file to extract all the text from the PDF file and store it in a raw file. The public ID of the generated file will be in the format: [pdf_public_id].extract_text.json.

    Note
    The text extraction result using the extract_text option may be different than the result you get if you use the OCR text detection and extraction add-on. For example, the OCR add-on includes exact coordinates of each line of text. Additionally, if your PDF contains images with text, the OCR add-on will capture this text, but the raw_convert:"extract_text" option will not.

Storage types

By default, when uploading assets to Cloudinary, both the original asset and its transformed versions are publicly available through a CDN. One way to restrict access to your assets is based on the asset's storage type.

Cloudinary supports three different storage types (type in the API):

  • upload - The asset is publicly available. This is the default storage type when uploading files.
  • private - Original assets are only accessible by a signed URL.
  • authenticted - Original assets and all their asset derivations are only accessible through signed URLs.

Important
This section only shows how to apply the type storage method feature as part of your upload command. See the Media access methods documentation for more information on all the access control methods features and who can access your files and when.

This section contains the following topics:

Private assets

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

To upload an asset as a private asset, you set the type parameter to private (instead of the default upload) when uploading the asset to Cloudinary. For example:

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

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

Note
You can make a private original asset 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 asset, which you can then provide to relevant customers. For details, see Providing time-limited access to private assets

Authenticated assets

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

To upload an asset as an authenticated asset, you set the storage type (type parameter) to authenticated (instead of the default upload) when uploading the asset to Cloudinary. For example:

If an asset was uploaded as 'authenticated', neither the asset nor any of its derived resources can be accessed without authentication. For example, the following URL returns an error:

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

Replacing existing assets

An existing image or video asset will be replaced by a newly uploaded file when overwrite is set to true and:

  • You upload a new media asset while specifying its public_id to be the same as an existing asset
  • The asset gets the same public ID as an existing one via the use_filename=true upload option
  • You use an upload preset where one of the above options is applied

If backups are enabled for your product environment, then when an asset is replaced, the previous version is backed up and can be restored if needed.

However, if the original (older) asset has already been generated and accessed, it might already be cached on the CDN. If an end-user accesses the identical URL soon after you overwrote the asset, they will still be accessing a CDN cached version rather than the new updated one.

You can ensure that a new version of an asset is delivered by setting the optional invalidate parameter to true when you overwrite an existing asset. This invalidates the previous media asset throughout the CDN. Note that it usually takes between a few seconds and a few minutes for the invalidation to fully propagate through the CDN.

Tip
An alternative method of ensuring that the latest versions of assets are delivered is to include version values in your delivery URLs. This method requires updating your delivery URLs in your production code when new versions of an asset are uploaded, but the change takes effect immediately. For details, see Asset versions.

Notes
  • Depending on your product environment setup, overwriting an asset may clear the tags, contextual, and structured metadata values for that asset. If you have a Master admin role, you can change this behavior for your product environment in the Media Library Preferences pane, so that these field values are retained when new version assets overwrite older ones (unless you specify different values for the tags, context, or metadata parameters as part of your upload).
  • There are a number of important considerations when using the invalidate functionality. For example, if there is no version number in a URL that includes a public ID with slashes, then by default, those URLs are not invalidated. For details on invalidating media assets, see Invalidating cached media assets on the CDN.

See also: Backups and version management

Upload response

A successful upload API call returns a response that includes the HTTP and HTTPS URLs for accessing the uploaded file, as well as additional information regarding the uploaded asset. Among these are the assigned Public ID and current version of the asset (used in the Media Explorer, Admin API, and for building transformation and delivery URLs), the asset's dimensions, the file format and a signature for verifying the response. Depending on the optional parameters passed, the response might also include valuable analysis data such as detected faces, prominent colors, exif and other embedded metadata, quality/accessibility and other sophisticated media analysis data.

Important
Cloudinary may add more fields to API responses and notifications in the future, so please ensure that your response parsing remains backwards compatible and wont be broken by the presence of unknown fields.

The following is an example of the JSON response returned:

Note
Although the URLs returned in the response are given with the version number, including the version in the delivery URL is optional.

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:

Verifying signatures in the JSON response

Cloudinary adds a signature value in the JSON response to various API methods. You can then compare the returned signature value in the JSON response with the value of a signature generated on your server side.

The signature is a hexadecimal message digest (hash value) created with an SHA (Secure Hash Algorithm) cryptographic function on the following parameters: public_id, version and api_secret.

Note
By default, Cloudinary supports both SHA-1 and SHA-256 digests for validation, and you can use either. The SDK methods use the SHA-1 algorithm by default, but you can use the SHA-256 algorithm instead by setting the signature_algorithm SDK configuration parameter to sha256. If you want to limit your account to allow only the SHA-256 digest for all your validations, submit a request.

Use the Cloudinary SDK's verify_api_response_signature method to verify the signature in the response.

Alternatively, you can use the Cloudinary SDK's api_sign_request method to generate a signature on your back-end for comparison purposes.

For example, the signature for the asset with a public_id of "sample" and a version of "1312461204":

Manually verifying a signature

You can manually generate the comparison signature instead of using the Cloudinary SDK's api_sign_request method.

  1. Create a string with the public_id and version parameters, in that 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 an SHA cryptographic function.

For example, if the asset has a public_id of "sample", a version of "1315060510", and your API secret is abcd:

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

An example of the above in Ruby on Rails:

Lazily migrate your existing assets to Cloudinary

You can migrate files on demand from a remote location using Cloudinary's auto-upload feature. With auto-upload, each asset is automatically uploaded to Cloudinary the first time the delivery URL for that asset is requested. After an asset has been auto-uploaded from the remote location, all further requests for the asset will reference the asset stored in your Cloudinary product environment.

The auto-upload feature is implemented by mapping a base remote URL to a specified folder in Cloudinary. Then, whenever accessing a Cloudinary delivery URL containing the defined folder prefix, the relevant media asset is automatically retrieved from the mapped remote URL, if it doesn't already exist in the folder.

For more details on how to set up your upload mapping and add on-the-fly transformations to request auto-uploaded assets, see the Auto Upload documentation.

Generating authentication signatures

When using the Cloudinary SDKs for any upload or admin method that requires a signature, the signature is automatically generated and added to the request. If, however, you are making direct calls to the REST API, you need to generate a signature yourself. You can do this manually, or by using a Cloudinary backend SDK signature generation method.

Manual signature generation

If you manually generate your own POST request, you need to authenticate the request with 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 or SHA-256 (Secure Hash Algorithm) cryptographic function.

Note
By default, Cloudinary supports both SHA-1 and SHA-256 digests for validation, and you can use either. The SDK methods use the SHA-1 algorithm by default, but you can use the SHA-256 algorithm instead by setting the signature_algorithm SDK configuration parameter to sha256. If you want to limit your account to allow only the SHA-256 digest for all your validations, submit a request.
  1. Create a string with the parameters used in the POST request to Cloudinary:
    • All parameters added to the method call should be included except: file, cloud_name, resource_type and your api_key.
    • Add the timestamp parameter.
    • Sort all the parameters 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 an SHA cryptographic 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 'https://www.example.com/sample.jpg', set its Public ID as sample_image, and eagerly generate 2 images:

  • Parameters to sign:
    • timestamp: 1315060510
    • public_id: sample_image
    • eager: w_400,h_300,c_pad|w_260,h_200,c_crop
  • Serialized sorted parameters in a single string:
    • eager=w_400,h_300,c_pad|w_260,h_200,c_crop&public_id=sample_image&timestamp=1315060510
  • String including the API secret that is used to create the SHA-1 signature:
    • eager=w_400,h_300,c_pad|w_260,h_200,c_crop&public_id=sample_image&timestamp=1315060510abcd
  • SHA-1 hexadecimal result:
    • bfd09f95f331f558cbd1320e67aa8d488770583e

The final request parameters for the upload POST request:

  • timestamp: 1315060510
  • public_id: sample_image
  • api_key: 1234
  • eager: w_400,h_300,c_pad|w_260,h_200,c_crop
  • file: https://www.example.com/sample.jpg
  • signature: bfd09f95f331f558cbd1320e67aa8d488770583e

For example, combining all the parameters in a cURL POST request to the demo product environment:

Note
The body of the POST request must be stringified, as seen in the example above (all parameters are included as a single string, even when the content type is JSON).

Or, using the POST request from the form example with a selected local file:

See also
Have a look at the Cloudinary Signatures quick reference for a summary of the payload string to sign for authentication signatures as well as information on other use cases that may require signature generation.

Using Cloudinary backend SDKs to generate SHA authentication signatures

You can use one of Cloudinary's backend SDKs to generate the authentication signature. The api_sign_request method uses the SHA-1 algorithm by default, but you can use the SHA-256 algorithm instead by setting the signature_algorithm SDK configuration parameter to sha256. Make sure that the timestamp is included in the params_to_sign object.

The following Node.js app contains two examples of using the api_sign_request method to provide a signature for uploading files:

  • signed-uploads/modules/signuploadwidget.js provides a signature for uploading files using the upload widget (corresponding to signed-uploads/public/js/uploadclientwidget.js)
  • signed-uploads/modules/signuploadform.js provides a signature for uploading files using a form (corresponding to signed-uploads/public/js/uploadclientform.js)

Run the app
  1. Click Remix to Edit
  2. Enter your Cloudinary product environment credentials in signed-uploads/public/js/config.js
  3. Click View App
  4. Try both upload options

This code is also available in GitHub.

See also
Watch this video tutorial explaining how to generate a signature using the Node.js SDK for use in a direct call to the REST API.

Important considerations for authentication signatures

When generating authentication signatures keep in mind the following:

  • The api_secret, which is a required element of the signature, should never be revealed to anyone who is not authorized, and therefore your signature should never be generated on the client side or inside your native application.
  • For mobile and other client-side applications, you must either use unsigned upload or have a server for processing the signature.
  • Signatures are valid for one hour from the timestamp value used to generate the signature.
  • Make sure to regenerate the signature if you dynamically change the payload of an upload request.

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

Upload options

In addition to the basic programmatic upload functionality described on this page, the rest of the pages in this Upload guide describe a variety of valuable functionality that you can take advantage of while uploading assets.

  • Transformations on upload: While uploading an asset, you can perform eager transformations that will already be generated and available before your users access them for the first time. You can also perform incoming transformations, which transform the original asset before storing it in Cloudinary, for example to limit an image size or a video duration.
  • Analysis on upload: As part of your upload, you can request to perform one or more analyses on the asset. The analysis results are stored with the asset. This data can be used to assist in searching, or the data can be used to add extra functionality to your applications. Some of the analysis options are built-in and avaialable to all users, others are available to certain plans, and the rest are provided via Cloudinary add-ons.
  • Upload presets: Upload presets enable you to centrally define a set of asset 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 set as signed or unsigned.

See also:

  • Upload API Reference: Provides both REST and SDK syntax, parameter details, and examples for all methods of the Upload API.
  • Upload Add-ons: Many of Cloudinary's add-ons can be activated by adding a parameter in your upload call. These add-ons enable you to take advantage of special deep-learning, AI, and other analytical capabilities offered by Cloudinary as well as other vision and image processing partners.
  • Asset administration: Covers options for managing your uploaded assets programmatically, including various CRUD options, backups and version management, notifications and webhooks, and authentication and signature options.

✔️ Feedback sent!

Rate this page: