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.
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 |
- 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
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 or an unauthenticated request.
- 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
orapi-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.
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.
- 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.
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:
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.
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. The code explorer makes use of the byte Content-Range entity-header HTTP specification to send the file in multiple calls.
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:
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.
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.
Tutorial contents
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:
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.
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:
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.
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.
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.
- 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 data stream
You can upload an actual data stream (byte array buffer):
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:
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
:
- 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 video would be delivered asmyname.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:
- 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 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 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 thefolder
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 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.
Asset types
Cloudinary supports many different file formats, which are categorized into three different asset types (resource_type
in the API):
- image (including animated images, PDFs and 3d models). For supported file formats, see Supported image formats and Uploading 3D models.
- video: All video and audio files For supported file formats, see Supported video formats and Supported audio formats.
- raw (any other file type)
This section contains the following topics:
- Passing the resource_type parameter to your upload call
- The 'auto' resource_type
- Uploading videos
- Uploading 3D models
- Uploading non-media files as raw files
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. - 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
toraw
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 isimage
, so you must set theresource_type
parameter when uploading videos. You can set theresource_type
parameter to auto 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. - 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:
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.
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.
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.
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
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.
- 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). - 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.
The following is an example of the JSON response returned:
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
.
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:
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.
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.
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.