Uploading assets
Last updated: Mar-26-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 more.
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. You can either upload using Cloudinary's REST API or one of Cloudinary's client libraries (SDKs), which wrap the upload API and simplify integration with web sites and mobile applications. Once uploaded, you can manage your assets using the Admin API and automatically deliver them, applying smart optimizations and transformations.
- Watch the Programmatic Upload video tutorial for a quick demo.
- Check out the Upload API Reference for a complete list of all the upload parameters.
Programmatic upload video tutorial
Watch this demo on how to quickly upload images, videos and other media files to Cloudinary for immediate deliverability using Cloudinary's Upload API in your development environment.
Uploading assets to the cloud
Cloudinary signed uploads are performed over HTTPS using a secure protocol based on your product environment's cloud_name
, api_key
and api_secret
parameters. Alternatively, you can implement an unsigned upload without an authentication signature.
- Usage limits for uploading, transforming and delivering files depend on your Cloudinary plan. For details, check the Account tab in your Cloudinary Console Settings.
- For additional information on how your overall account usage is calculated (including storage and bandwidth), see the Cloudinary Pricing page and this KB article.
- You can set your email preferences to receive notifications regarding your account usage.
While you can use the REST API directly within your custom code to implement signed uploads, it is simpler and recommended to use Cloudinary's backend SDKs:
- Ruby/Rails server-side upload
- PHP server-side upload
- Python server-side upload
- Node.js server-side upload
- Java server-side upload
- .NET server-side upload
- Go server-side upload
When using Cloudinary's SDKs for signed uploads, the cloud_name
, api_key
and api_secret
are generally configured globally, but they can be provided with each upload call as well.
The Cloudinary upload
method performs an authenticated upload API call over HTTPS:
options = {}
) available for the upload method, see the Upload API reference.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.
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 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
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:
- The public ID value for
image
andvideo
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 specifymyname.mp4
as the public_id, then the image would be delivered asmyname.mp4.mp4
. - For
raw
asset types only, the file extension should be specified as part of the public_id.For more details on asset types, see Asset types.
- 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:
- You cannot use 'v' followed by numeric characters as the name of a path element in your public ID.
- 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 aversion
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 Library 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 Library. If an asset is moved to a different folder in the Media Library, 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 Library. Additionally, if in this mode, you should use the new
asset_folder
parameter instead of thefolder
parameter mentioned above to set the Media Library folder. Whether or not you define an asset folder for purposes of organizing assets in the Media Library, if you also want yourpublic_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
andasset_folder
response keys. - For more details on dynamic folders mode, see Dynamic folders - New Upload API parameters.
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
:
Multiple derived assets created by transformations of an uploaded asset share the same Public ID as the original asset. They are further identified by the specific transformation that created them. For more information on transformations, see the image transformation and video transformation guides.
?
&
#
\
%
<
>
. In addition, spaces and forward slashes (/
) cannot be used as the first or last character of the Public ID.File source options
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 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.
- 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:
-
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.
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
- In Amazon's AWS S3 Console, select the relevant bucket.
- In the Bucket Policy properties, paste the following policy text.
Keep theVersion
value as shown below, but changeBUCKETNAME
to the name of your bucket.
If a policy already exists, append this text to the existing policy:
.
character are not supported for this purpose.How to set read access on a Google Storage bucket
- In your GCP console, go to your Google bucket's main page.
- Select to edit bucket permissions.
- Add
service@cloudinary-gcs-production.iam.gserviceaccount.com
as a member and give it the Storage Object Viewer role.
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 100 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:
Asset types
Cloudinary supports many different file formats, which it categorizes into three different asset types (resource_type
in the API):
- image (including animated images). For supported file formats, see Supported image formats.
- video (also includes audio files). For supported file formats, see Supported video formats and Supported audio formats.
- raw (any other file type)
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.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.
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 defaultresource_type
. When uploading video or raw file types, you must pass theresource_type
option either with the valueauto
or with the relevant specific asset type. - When using direct image uploading from the browser, resource type is set to
auto
by default.
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.
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
isimage
, so you must set theresource_type
parameter when uploading videos. You can set theresource_type
parameter toauto
to instruct Cloudinary to automatically detect the asset type, or you can set the parameter tovideo
if you know in advance that you are uploading a video file. For more details, see The 'auto' resource_type. - 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 limitations to transforming larger videos on the fly (40 MB for free plans, 300 MB for paid plans). 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:
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.
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 yourraw_convert
parameter when uploading an Office document to instruct the Aspose Document Conversion add-on to generate a PDF image file from yourraw
office document. - Specify
google_speech
when uploading a video to instruct the Google AI Video Transcription add-on to generate an automatic transcriptraw
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 araw
file. The public ID of the generated file will be in the format: [pdf_public_id].extract_text.json.NoteThe text extraction result using theextract_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 theraw_convert:"extract_text"
option will not.
Asset versions
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.
The version component is an optional part of Cloudinary delivery URLs that can be added to bypass the CDN cached version and force delivery of the newest asset. 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.
- Delivering the URL without a version value will deliver the cached version on the CDN if available or will request the latest version from Cloudinary if not cached (or when the cached version expires).
- Delivering the URL with a version will deliver the cached CDN version only if the cached version matches the requested version number. Otherwise, it will bypass the cached CDN version and immediately request and deliver the latest version from Cloudinary.
Example image delivery URL without version:
https://res.cloudinary.com/demo/image/upload/sample.jpg
Example image delivery URL with version:
https://res.cloudinary.com/demo/image/upload/v1371750447/sample.jpg
As an alternative to using versions to ensure that a new version of an asset is delivered, you can set the invalidate
parameter to true
while uploading a new version of an asset in order to invalidate 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, while the version
component takes effect immediately.
- 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
, ormetadata
parameters as part of your upload). - You cannot use 'v' followed by numeric characters as the name of a public ID path component.
- 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
Chunked asset upload
In order 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.
upload_large
method is supported only in the Cloudinary SDKs. When directly calling the REST API, you can make use of the byte Content-Range entity-header HTTP specification to send the file in multiple calls. See Code explorer: Chunked asset upload from the client side. 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
For example, uploading a large video file named my_large_video.mp4
:
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 video file named my_large_video.mp4
and setting chunk size to 6 Megabytes:
Code explorer: Chunked asset upload from the client side
Here's an example of uploading large files using pure client-side code, in this case React.
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.
Upload response
An 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 Library, Admin API, and for building transformation and delivery URLs), the asset's dimensions, the file format and a signature for verifying the response. The following is an example of the JSON response returned:
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
.
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.
- Create a string with the
public_id
andversion
parameters, in that order. Separate the parameter names from their values with an=
and join the parameter/value pairs together with an&
. - Append your API secret to the end of the string.
- 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
- public_id:
- 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:
Control access to assets
By default, when uploading assets to Cloudinary, both the original asset and its transformed versions are publicly available through a CDN. You can use random Public IDs to make it harder to guess asset URLs (Cloudinary's default behavior if no Public ID is specified), but you might still want further access control.
This section shows how to apply these access control features as part of your upload command. For more information on all of these features and how they impact user acess upon delivery, see Media access control.
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
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 delivery 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 assets can be accessed without authentication. For example, the following URL returns an error:
https://res.cloudinary.com/demo/image/authenticated/sample.jpg
Access mode
The access_mode
parameter allows a resource with the delivery type upload
to behave as if it's of type 'authenticated' while still using the default upload
delivery type in URLs. The asset can later be made public by changing its access_mode via the Admin API, without having to update any 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
:
Direct uploading from the browser
The upload samples shown in the sections above allow your code to upload files to Cloudinary. In this flow, 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.
A more efficient and powerful option is to allow your users to upload assets 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.
One option for directly uploading 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 the relevant SDK integration guide and the blog post on Direct upload made easy, from browser or mobile app to the cloud.
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.
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 product environment from the Upload Settings page. Enabling unsigned uploading also creates an upload preset with a unique name, which explicitly allows uploading of assets without authentication. The preset is also used to define which upload options will be applied to assets 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 assets 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.
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 to the Cloudinary demo
product environment with the unsigned_1
upload preset:
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.
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 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:
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.
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.
Uploading with a direct call to the REST 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 product environment. -
resource_type
is the type of file to upload. Valid values:image
,raw
,video
andauto
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 (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 a private storage bucket (S3 or Google Storage) URL of a whitelisted bucket. -
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 the API Secret of your Cloudinary product environment. The signature is valid for 1 hour. See Generating 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 a private storage bucket (S3 or Google Storage) URL of a whitelisted bucket. -
upload_preset
- The name of an unsigned upload preset that you defined for unsigned uploading.
Optional parameters:
See the upload method of the Upload API for all parameters available for uploading files.
public_id
, folder
, callback
, tags
, context
, face_coordinates
, custom_coordinates
. Additional upload parameters can be defined within your 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.
See also: Code explorer: Chunked asset upload from the client side
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 above unauthenticated example, just appending your API key, timestamp and signature to formData
. See signed-uploads/public/js/uploadclientform.js in the following example.
- Click Remix to Edit
- Enter your Cloudinary credentials in signed-uploads/public/js/config.js
- Click View App
- Click the Upload Files Using a Form link
This code is also available in GitHub.
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.
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.- 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 yourapi_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&
.
- All parameters added to the method call should be included except:
- Append your API secret to the end of the string.
- 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
- timestamp:
- Serialized sorted parameters in a single string:
eager=w_400,h_300,c_pad|w_260,h_200,c_crop&public_id=sample_image×tamp=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×tamp=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:
Or, using the POST request from the form example with a selected local file:
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)
- Click Remix to Edit
- Enter your Cloudinary product environment credentials in signed-uploads/public/js/config.js
- Click View App
- Try both upload options
This code is also available in GitHub.
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.
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:
Uploading 3D models
Cloudinary supports 3D models in various formats. Where the format requires or references other 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 Library.
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:
Retrieving and delivering remote files on the fly
Auto-Upload and Fetch are two similar features for automatically retrieving files from existing remote locations using dynamic URLs.
Fetch enables on-the-fly transformation and optimized delivery of existing remote images and videos via CDN. Fetched assets are cached on your Cloudinary product environment for performance reasons. Paid customers can request to enable a refresh option for checking the remote asset on a regular basis, and if the remote asset changes, the cached asset is updated accordingly.
For example, to fetch a remote image of Benedict Cumberbatch fetched by Cloudinary from WikiMedia:

Auto Upload enables on-the-fly transformation of existing remote media files (images, videos, and other raw file types) and optimized delivery via a CDN, while simultaneously uploading the file to Cloudinary for further management, and thus benefiting from a variety of additional features (just like any other media file that you directly uploaded to Cloudinary). This feature is very useful for lazy migration of media assets from a remote location to Cloudinary with minimal effort on your side.
For example, if you create a folder called remote_media
and then map it to the URL prefix https://upload.wikimedia.org/wikipedia/
, you can generate a Cloudinary delivery URL that substitutes the remote_media
folder prefix for the URL prefix. Where the original URL is:
https://upload.wikimedia.org/wikipedia/commons/7/75/Benedict_Cumberbatch_2011.jpg
With the Auto Upload feature you would now access the following Cloudinary URL:

The image is dynamically retrieved from WikiMedia the first time this URL is accessed and then it is uploaded and stored in Cloudinary just like any other uploaded asset with a Public ID of remote_media/commons/7/75/Benedict_Cumberbatch_2011.jpg
.
For complete details on the Auto-Upload and Fetch features, see Deliver remote media files.
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.