> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Create Product Image

POST https://api.bigcommerce.com/stores/{store_hash}/v3/catalog/products/{product_id}/images
Content-Type: application/json

Creates a *Product Image*.

 **Required Fields**
- `image_file`, or
- `image_url`

**Usage Notes**
- `image_url` - `255` character limit
- `Content-Type` - For `image_file`, use the `multipart/form-data` media type. For `image_url`, use the `application/json` type. See [Adding product images](/developer/docs/admin/catalog-and-inventory/products-overview#adding-product-images) for more information.
- When you upload an `image_file`, send `description`, `sort_order`, and `is_thumbnail` as separate form fields in the same `multipart/form-data` request.
- You can create only one image at a time. A product can have up to 1000 images.
- Supported image file types are BMP, GIF, JPEG, PNG, WBMP, XBM, and WEBP.
- Each image file or image uploaded by URL can be up to 8 MB.

Reference: https://docs.bigcommerce.com/developer/api-reference/rest/admin/catalog/products/images/create-product-image

## Authentication

- `X-Auth-Token` header (required) — ### OAuth scopes | UI Name | Permission | Parameter | |:--------|:-----------|:----------| | Products | modify | `store_v2_products` | | Products | read-only | `store_v2_products_read_only` | ### Authentication header | Header | Argument | Description | |:-------|:---------|:------------| | `X-Auth-Token` | `access_token` | For more about API accounts that generate `access_token`s, see our [Guide to API Accounts](/developer/docs/overview/api-fundamentals/api-accounts#api-accounts). | ### Further reading For example requests and more information about authenticating BigCommerce APIs, see [Authentication and Example Requests](/developer/docs/overview/api-fundamentals/api-accounts#x-auth-token-header-example-requests). For more about BigCommerce OAuth scopes, see our [Guide to API Accounts](/developer/docs/overview/api-fundamentals/api-accounts#oauth-scopes). For a list of API status codes, see [API Status Codes](/developer/api-reference/rest/overview#rest-http-status-codes).

## Request

### Path parameters

- `product_id` (integer, required) — The ID of the `Product` to which the resource belongs.
- `store_hash` (string, required) — Permanent ID of the BigCommerce store.

### Headers

- `Accept` (string, required, default: application/json) — The [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) of the response body.

### Body (application/json)

This endpoint expects a productImage_Post_Put.

- `date_modified` (datetime, optional) — The date on which the product image was modified. Read-Only.
- `description` (string, optional) — The description for the image.
- `image_url` (string, optional) — The URL for an image displayed on the storefront when the conditions are applied. Limit of 8MB per file. Cannot be used with `image_file`.
- `is_thumbnail` (boolean, optional) — Flag for identifying whether the image is used as the productʼs thumbnail.
- `product_id` (integer, optional) — The unique numeric identifier for the product with which the image is associated.
- `sort_order` (integer, optional) — The order in which the image will be displayed on the product page. Higher integers give the image a lower priority. When updating, if the image is given a lower priority, all images with a `sort_order` the same as or greater than the imageʼs new `sort_order` value will have their `sort_order`s reordered.

## Response

### 200

Success

- `data` (CatalogProductsProductIdImagesPostResponsesContentApplicationJsonSchemaData, optional)
- `meta` (metaEmpty_Full, optional) — Response metadata.

## Errors

### 400 Bad Request Error

Bad Request. The requested resource could not be downloaded and may be invalid. Possible reasons include malformed request syntax or the file host blocking requests.

### 404 Not Found Error

The product ID does not exist.

- `status` (integer, optional) — 404 HTTP status code.
- `title` (string, optional) — The error title describing the particular error.
- `type` (string, optional)
- `instance` (string, optional)

### 422 Unprocessable Entity Error

Unprocessable Entity. May occur if: - The `Content-Type` header is set to `multipart/form-data` rather than `application/json` when creating a product image using `image_url`. - A field fails validation, such as a `sort_order` that isn't an integer or an `is_thumbnail` that isn't a boolean. This applies to both `application/json` and `multipart/form-data` requests.

- `status` (double, required)
- `title` (string, required)
- `type` (string, required)

## Types

### CatalogProductsProductIdImagesPostResponsesContentApplicationJsonSchemaData

- application/json: application/json
- multipart/form-data: multipart/form-data

### metaEmpty_Full

Response metadata.

### application/json

Common ProductImage properties.

- `id` (integer, optional) — The unique numeric ID of the image; increments sequentially.
- `product_id` (integer, optional) — The unique numeric identifier for the product with which the image is associated.
- `url_zoom` (string, optional) — The zoom URL for this image. By default, this is used as the zoom image on product pages when zoom images are enabled. You should provide an image smaller than 1280x1280; otherwise, the API returns a resized image.
- `url_standard` (string, optional) — The standard URL for this image. By default, this is used for product-page images.
- `url_thumbnail` (string, optional) — The thumbnail URL for this image. By default, this is the image size used on the category page and in side panels.
- `url_tiny` (string, optional) — The tiny URL for this image. By default, this is the image size used for thumbnails beneath the product image on a product page.
- `date_modified` (datetime, optional) — The date on which the product image was modified.
- `is_thumbnail` (boolean, optional) — Flag for identifying whether the image is used as the productʼs thumbnail.
- `sort_order` (integer, optional) — The order in which the image will be displayed on the product page. Higher integers give the image a lower priority. When updating, if the image is given a lower priority, all images with a `sort_order` the same as or greater than the imageʼs new `sort_order` value will have their `sort_order`s reordered.
- `description` (string, optional) — The description for the image.
- `image_url` (string, optional) — Must be a fully qualified URL path, including protocol. Limit of 8MB per file.

### multipart/form-data

- `id` (integer, optional) — The unique numeric ID of the image; increments sequentially.
- `product_id` (integer, optional) — The unique numeric identifier for the product with which the image is associated.
- `image_file` (string, optional) — The local path to the original image file uploaded to BigCommerce. Use image_url when creating a product. A `multipart/form-data` media type. Must be sent as a multipart/form-data field in the request body. Limit of 8 MB per file.
- `url_zoom` (string, optional) — The zoom URL for this image. By default, this is used as the zoom image on product pages when zoom images are enabled. You should provide an image smaller than 1280x1280; otherwise, the API returns a resized image.
- `url_standard` (string, optional) — The standard URL for this image. By default, this is used for product-page images.
- `url_thumbnail` (string, optional) — The thumbnail URL for this image. By default, this is the image size used on the category page and in side panels.
- `url_tiny` (string, optional) — The tiny URL for this image. By default, this is the image size used for thumbnails beneath the product image on a product page.
- `date_modified` (datetime, optional) — The date on which the product image was modified.
- `is_thumbnail` (boolean, optional) — Flag for identifying whether the image is used as the productʼs thumbnail.
- `sort_order` (integer, optional) — The order in which the image will be displayed on the product page. Higher integers give the image a lower priority. When updating, if the image is given a lower priority, all images with a `sort_order` the same as or greater than the imageʼs new `sort_order` value will have their `sort_order`s reordered.
- `description` (string, optional) — The description for the image.

## Examples

**Request**

```json
{
  "description": "Product image",
  "image_url": "https://example.com/path/to/product-image.png",
  "is_thumbnail": false,
  "sort_order": 1
}
```

**SDK Code**

```python Create a product image (application/json)
import requests

url = "https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images"

payload = {
    "description": "Product image",
    "image_url": "https://example.com/path/to/product-image.png",
    "is_thumbnail": False,
    "sort_order": 1
}
headers = {
    "X-Auth-Token": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Create a product image (application/json)
const url = 'https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images';
const options = {
  method: 'POST',
  headers: {'X-Auth-Token': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"description":"Product image","image_url":"https://example.com/path/to/product-image.png","is_thumbnail":false,"sort_order":1}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Create a product image (application/json)
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images"

	payload := strings.NewReader("{\n  \"description\": \"Product image\",\n  \"image_url\": \"https://example.com/path/to/product-image.png\",\n  \"is_thumbnail\": false,\n  \"sort_order\": 1\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-Auth-Token", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Create a product image (application/json)
require 'uri'
require 'net/http'

url = URI("https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-Auth-Token"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"description\": \"Product image\",\n  \"image_url\": \"https://example.com/path/to/product-image.png\",\n  \"is_thumbnail\": false,\n  \"sort_order\": 1\n}"

response = http.request(request)
puts response.read_body
```

```java Create a product image (application/json)
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images")
  .header("X-Auth-Token", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"description\": \"Product image\",\n  \"image_url\": \"https://example.com/path/to/product-image.png\",\n  \"is_thumbnail\": false,\n  \"sort_order\": 1\n}")
  .asString();
```

```php Create a product image (application/json)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images', [
  'body' => '{
  "description": "Product image",
  "image_url": "https://example.com/path/to/product-image.png",
  "is_thumbnail": false,
  "sort_order": 1
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-Auth-Token' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Create a product image (application/json)
using RestSharp;

var client = new RestClient("https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images");
var request = new RestRequest(Method.POST);
request.AddHeader("X-Auth-Token", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"description\": \"Product image\",\n  \"image_url\": \"https://example.com/path/to/product-image.png\",\n  \"is_thumbnail\": false,\n  \"sort_order\": 1\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Create a product image (application/json)
import Foundation

let headers = [
  "X-Auth-Token": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "description": "Product image",
  "image_url": "https://example.com/path/to/product-image.png",
  "is_thumbnail": false,
  "sort_order": 1
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.bigcommerce.com/stores/:store_hash/v3/catalog/products/:product_id/images")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```