Upload an image

August 20, 2026 · View on GitHub

When to use

Server-side upload of a local file, buffer, stream, or remote URL into your Cloudinary product environment. For uploads started in a browser, see Sign a browser upload.

Complete flow

const cloudinary = require('cloudinary').v2; // reads CLOUDINARY_URL

async function main() {
  const result = await cloudinary.uploader.upload(
    'https://res.cloudinary.com/demo/image/upload/sample.jpg', // file path, URL, data URI, or stream
    {
      public_id: 'examples/uploaded-sample', // stable, addressable ID; omit for a random one
      overwrite: true
    }
  );

  console.log(result.public_id);   // 'examples/uploaded-sample'
  console.log(result.secure_url);  // canonical delivery URL of the original
  console.log(result.width, result.height, result.format, result.bytes);
  return result;
}

main().catch((error) => {
  const { message } = error.error || error;
  console.error(`Upload failed: ${message}`);
  process.exitCode = 1;
});

source may be a file path, a remote URL, a data URI, or a stream (cloudinary.uploader.upload_stream for buffers/streams).

Result fields to keep

Store asset_id. It never changes; public_id changes when an asset is renamed or moved.

console.log(result.asset_id);

Look assets up with api.resource_by_asset_id (or api.resources_by_asset_ids, api.restore_by_asset_ids, api.delete_resources_by_asset_ids in bulk). Every lookup returns the public_id for delivery URLs and updates.

Size limits

Two separate limits apply, and they fail the same way:

  • 100 MB per request. A single upload call cannot exceed this, whatever your plan. Above it, use upload_large — it splits the file into chunks (20 MB by default, set with chunk_size) and uploads them sequentially.
  • Your product environment's maximum asset size, which varies by plan and is unrelated to the per-request ceiling. upload_large does not raise it.

Read the real values for your environment rather than assuming:

const { media_limits } = await cloudinary.api.usage();
console.log(media_limits.image_max_size_bytes);
console.log(media_limits.video_max_size_bytes);
console.log(media_limits.image_max_px, media_limits.asset_max_total_px);

If an asset exceeds the environment maximum, chunking will not help — compress or resize it before uploading, or upgrade the plan.

Troubleshooting

  • Must supply api_key — configuration missing; see Configure Cloudinary.
  • File size too large — see Size limits; either the request exceeded the 100 MB single-request ceiling, or the asset exceeds your product environment's maximum.
  • Remote URL fetch failures — the URL must be publicly reachable from Cloudinary.