> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# Go image and video upload

[githublink]: https://github.com/cloudinary-community/cloudinary-examples/tree/main/examples/go-image-upload

Cloudinary provides an API for uploading images, videos, and any other kind of file to the cloud. Files uploaded to Cloudinary are stored safely in the cloud with secure [backups and revision history](backups_and_version_management). Cloudinary's APIs allow secure uploading from your servers, directly from your visitors' browsers or mobile applications, or fetched via remote public URLs. 

Cloudinary's Go SDK wraps Cloudinary's upload API and simplifies the integration. Methods are available for easily performing image and video uploads to the cloud.

This page covers common usage patterns for Go image and video upload with Cloudinary.

For details on all available upload functionality, see the [Upload](upload_images) guide, and the [upload](image_upload_api_reference#upload) method of the Upload API Reference.
> **TIP**: Cloudinary's [Upload widget](upload_widget) provides an alternative to using a Cloudinary SDK to add upload functionality to your application, eliminating the need to develop in-house interactive upload capabilities. The upload widget is an interactive, feature rich, simple-to-integrate user interface that enables you to add Cloudinary upload support to your website. The widget can be easily embedded in your web application with just a few lines of JavaScript code. See the [Upload widget](upload_widget) documentation for detailed information. 

![Upload widget main screen](https://cloudinary-res.cloudinary.com/image/upload/q_auto/f_auto/bo_1px_solid_grey/docs/upload_widget_dev_default_new.png "width: 600, with_code:false, with_url:false")

## Server-side upload
  
You can upload images, videos, or any other raw file to Cloudinary using Go code. Uploading is done over HTTPS using a secure protocol based on your product environment's `api_key` and `api_secret` parameters. 
  
### Go image upload

The following method uploads an image to the cloud:
  
```go
resp, err := cld.Upload.Upload(ctx, file, options);
```

For example, uploading a local image file named 'my\_image.jpg':
  
```go
resp, err := cld.Upload.Upload(ctx, "my_image.jpg", uploader.UploadParams{});
```

The file to upload can be specified as a local path, a remote HTTP or HTTPS URL, an allowlisted storage bucket (S3 or Google Storage) URL, a Base64 data URI, or an FTP URL. For details and code examples of uploading using each of these data source types, see [Required upload parameters](upload_parameters#required_file_parameter). 

For details on all available upload functionality, see the [Upload](upload_images) guide, and the [upload](image_upload_api_reference#upload) method of the Upload API Reference.

#### Customizing uploads
You can customize your upload by passing additional parameters in the options object. This allows you to assign metadata, organize assets, reuse filenames, request moderation, and more. For more details, see [Customizing uploads](upload_parameters).

**Example: Upload with tags, metadata, moderation, and analysis**

This example sets:

* **Tags**: `summer`, `new-arrival` 

* **Contextual metadata**:
  * Set the `department` as `apparel`
  * Set the `photographer` as `Jane Doe`

* **Structured metadata**:
  * Set the field with external ID `sku-id` as `SKU12345678`
  * Set the field with external ID `product-id` as `PROD-9081-WHT`

* **Additional options**:
  * `use_filename: true` – use original file name as the base for public ID
  * `unique_filename: true` – append a random suffix to avoid overwriting
  * `moderation: "webpurify"` – automatically flag assets for moderation
  * `quality_analysis: true` – request Cloudinary’s AI quality scoring

> **NOTE**:
>
> Before running this example in your product environment, [create](media_library_for_developers#managing_structured_metadata_fields) text fields with external IDs `sku-id` and `product-id`, and register for the **WebPurify** [add-on](cloudinary_add_ons). Replace `/home/my_image.jpg` with the path to an image in your local directory.
```go
resp, err := cld.Upload.Upload(ctx, "/home/my_image.jpg", uploader.UploadParams{
    UseFilename:     api.Bool(true),
    UniqueFilename:  api.Bool(true),
    Moderation:      "webpurify",
    Tags:            []string{"summer", "new-arrival"},
    Context: map[string]string{
        "department":  "apparel",
        "photographer": "Jane Doe",
    },
    Metadata: map[string]string{
        "sku-id":     "SKU12345678",
        "product-id": "PROD-9081-WHT",
    },
    QualityAnalysis: api.Bool(true),
})

if err != nil {
    log.Fatalf("Upload failed: %v", err)
}

log.Printf("Upload successful: %s", resp.SecureURL)
```

For details on all available upload functionality, see the [Upload](upload_images) guide, and the [upload](image_upload_api_reference#upload) method of the Upload API Reference.

#### Video tutorial: Image upload

Watch this video tutorial to learn more about uploading images in Go:

  This video is brought to you by Cloudinary's video player - embed your own!Use the controls to set the playback speed, navigate to chapters of interest and select subtitles in your preferred language.

> **TIP**: :title=View the code

You can find the code from this tutorial in [GitHub][githublink].
#### Tutorial contents This tutorial presents the following topics. Click a timestamp to jump to that part of the video.### Introduction
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=0 :sec=00 :player=cld} | One of the most important parts of your workflow is getting your images and videos into the Cloudinary Media Library. In this tutorial, you'll learn how to use the Go SDK to upload one or multiple images to Cloudinary.

### Upload a single image from your local file system
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=0 :sec=17 :player=cld} | Once the Cloudinary Go module is installed, imported, and configured, you can upload local images from your directory. Start by creating a context with `context.Background()` and save it to the variable `ctx`. Then call the Cloudinary uploader method, passing the image path as an argument. Make sure to reference the correct path in your file system. Save the upload response in a variable and add proper error handling. Finally, print out the response as formatted JSON for easy reading.

```go
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    
    "github.com/cloudinary/cloudinary-go/v2"
    "github.com/cloudinary/cloudinary-go/v2/api/uploader"
    "github.com/joho/godotenv"
)

func main() {
    // Load the environment variables from the .env file
    err := godotenv.Load()
    if err != nil {
        log.Fatalf("Error loading .env file: %v", err)
    }
    
    // Initialize Cloudinary with credentials from the environment variable CLOUDINARY_URL
    cld, err := cloudinary.New()
    if err != nil {
        log.Fatalf("Failed to initialize Cloudinary: %v", err)
    }
    // Create a context
    ctx := context.Background()
    
    // Upload the image
    resp, err := cld.Upload.Upload(ctx, "images/butterfly.jpeg", uploader.UploadParams{})
    if err != nil {
        log.Fatalf("Error uploading image: %v", err)
    }
    
    // Marshal the data into a pretty JSON string
    response, err := json.MarshalIndent(resp, "", "  ")
    if err != nil {
        fmt.Println("Failed to generate JSON", err)
        return
    }

    // Log the response
    fmt.Println("Upload response:")
    fmt.Println(string(response))
}
```

### Upload response
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=0 :sec=51 :player=cld} | When you run the script, it returns a comprehensive upload response containing metadata and the delivery URL for your image. You can then open the image in a browser window to verify it's delivered correctly from Cloudinary.

### Upload multiple images from your local file system
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=1 :sec=01 :player=cld} | To upload multiple files efficiently, first define their file paths in an array, then use a Go loop to iterate over this array. Inside the loop, place the Cloudinary `uploader` code and replace the static image path with the loop variable that represents the current image path. Be sure to add proper error handling to catch any issues during the upload process. This approach ensures each image in the array gets uploaded successfully. For cleaner output, instead of printing the entire upload response for each image, you can log only the secure URLs.

```go
// Array of image paths
imagePaths := []string{
        "images/butterfly.jpg",
        "images/landscape.jpg",
        "images/portrait.jpg",
}
    
// Upload the images
for _, path := range imagePaths {
    result, err := cld.Upload.Upload(ctx, path, uploader.UploadParams{})
    if err != nil {
        log.Printf("Error uploading image %s: %v", path, err)
        continue
    }
        
// Log the delivery URLs
fmt.Printf("Path: $x\nDelivery Url: %s\n\n", path, resp.SecureURL)
}
```

### Upload a single image from a remote URL
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=1 :sec=41 :player=cld} | While we've covered uploading images from your local directory, Cloudinary's uploader is versatile and accepts images from other sources as well. You can upload images directly from remote URLs, allowing you to pull images from other servers directly into your Cloudinary account. The process is straightforward: simply replace the local image path with a web image URL in your uploader call. When you run the code, it returns the Cloudinary delivery URL for the uploaded image, which you can then open in a browser to verify the successful upload.

```go
// Upload from remote URL
resp, err := cld.Upload.Upload(ctx, "https://raw.githubusercontent.com/cloudinary-devs/cld-docs-assets/refs/heads/main/assets/images/models.jpg", uploader.UploadParams{})
if err != nil {
    log.Printf("Error uploading image:", err)
    return
}
// Log the delivery URL
fmt.Printf("Delivery URL: %s\n\n", resp.SecureURL)
```
---

### Go video upload

You upload videos in exactly the same way as images. 

The following example uploads `dog.mp4` to Cloudinary and stores it with the public ID `dog_closeup`. It also performs two eager transformations that resize the video to a square and a small rectangle.

```go
resp, err := cld.Upload.Upload(ctx, "dog.mp4", uploader.UploadParams{
  PublicID:  "dog_closeup",
  Eager:  "w_300,h_300,c_pad,ac_none|w_160,h_100,c_crop,g_south,ac_none",
  EagerAsync: api.Bool(true),
  EagerNotificationURL: "https://mysite.example.com/notify_endpoint"
});
```

### Upload response

By default, uploading is performed synchronously. Once finished, the uploaded image or video is immediately available for transformation and delivery. An upload call returns a `struct` with content similar to the following:
  
```go
&{
  AssetID:aac8fd89108ff834dd27f979fd9ce77e 
  PublicID:hl22acprlomnycgiudor 
  Version:1591095352 
  VersionID:909700634231dbaaf8b06d7a5940299e
  Signature:86922996d63e596464ea3d7a5e86e8de8123f23f 
  Width:1200 
  Height:1200 
  Format:jpg 
  ResourceType:image 
  CreatedAt:2020-06-02 10:55:52 +0000 UTC 
  Tags:[] 
  Pages:0 
  Bytes:460268 
  Type:upload 
  Etag:2c7e88604ba3f340a0c5bc8cd418b4d9 
  Placeholder:false 
  URL:  http://res.cloudinary.com/demo/image/upload/v1591095352/hl22acprlomnycgiudor.jpg 
  SecureURL:  https://res.cloudinary.com/demo/image/upload/v1591095352/hl22acprlomnycgiudor.jpg
  AssetFolder: ,
  DisplayName:do8wnccnlzrfvwv1mqkq 
  Overwritten:true 
  OriginalFilename:my_image 
  ApiKey:614335564976464
  Error:{Message:}
}

```

```json
{
    "asset_id": "86ca8ba13b17e21d23534b7e842b8847",
    "public_id": "do8wnccnlzrfvwv1mqkq",
    "version": 1719309138,
    "version_id": "1a2b0a8ef0bf8e9f20a922f38704eda6",
    "signature": "afb6a3374ba12e4e0307e23e625d939b242ddb5c",
    "width": 1920,
    "height": 1281,
    "format": "jpg",
    "resource_type": "image",
    "created_at": "2024-06-25T09:52:18Z",
    "tags": [],
    "bytes": 310479,
    "type": "upload",
    "etag": "a8f8236455d352b8cee6aba0e3fbc87e",
    "placeholder": false,
    "url": "http://res.cloudinary.com/cld-docs/image/upload/v1719309138/do8wnccnlzrfvwv1mqkq.jpg",
    "secure_url": "https://res.cloudinary.com/cld-docs/image/upload/v1719309138/do8wnccnlzrfvwv1mqkq.jpg",
    "asset_folder": "",
    "display_name": "do8wnccnlzrfvwv1mqkq",
    "original_filename": "f5lq8lfq8pfj0xmd9dak",
    "api_key": "614335564976464"
}
```

The response includes HTTP and HTTPS URLs for accessing the uploaded media asset as well as additional information regarding the uploaded asset: The public ID, resource type, width and height, file format, file size in bytes, a signature for verifying the response and more.  

### File sources

Cloudinary's Go library supports uploading files from various sources.

* You can upload an asset by specifying a local path of an image file. For example:

    ```go
    resp, err := cld.Upload.Upload(ctx,"/home/my_image.jpg",uploader.UploadParams{});
    ```

* If your assets are already publicly available online, you can specify their remote HTTP URLs instead of uploading the actual data. In this case, Cloudinary will fetch the asset from its remote URL for you. This option allows for a much faster migration of your existing assets. Here's an example:

    ```go
    resp, err := cld.Upload.Upload(ctx,"https://www.example.com/image.jpg",uploader.UploadParams{});
    ```
* If you have existing assets in an Amazon S3 bucket, you can point Cloudinary to their S3 URLs. Note - this option requires a quick manual setup. Contact us and we'll guide you on how to allow Cloudinary access to your relevant S3 buckets.

    ```go
    resp, err := cld.Upload.Upload(ctx,"s3://my-bucket/my-path/example.jpg",uploader.UploadParams{});
    ```
    
For more information on file sources for upload, see [File sources](upload_parameters#file_sources).

## Direct uploading from the browser

The upload samples shown above allow your server-side Go code to upload media assets to Cloudinary. In this flow, if you have a web form that allows your users to upload images or videos, the media file's data is first sent to your server and then uploaded to Cloudinary. 

A more efficient and powerful option is to allow your users to upload images and videos in your client-side code directly from the browser to Cloudinary instead of going through your servers. This method allows for faster uploading and a better user experience. It also reduces load from your servers and reduces the complexity of your Go applications.

You can upload files directly from the browser using signed or unsigned calls to the upload endpoint, as shown in these examples: [Upload multiple files using a form](client_side_uploading#code_explorer_upload_multiple_files_using_a_form_unsigned).

> **READING**:
>
> * For more information on uploading media assets, see the [Upload](upload_images) guide. 

> * For details on all available upload parameters, see the [upload](image_upload_api_reference#upload) method of the Upload API Reference.

