7

This is how I creating product.

{
  "product": {
    "attribute_set_id": 4,
    "type_id": "simple",
    "sku": "B201-SKU",
    "name": "B201",
    "price": 25,
    "status": 1,
    "custom_attributes": {
      "description": "Heavy Duty Brake Cables",
      "meta_description": "Some describing text"
    }
  }
}

3 Answers 3

12

You need an additional POST with the route :

http://YOUR_MAGENTO_ADDRESS/index.php/rest/V1/products/B201-SKU/media

The basic template JSON would be something like:

{
    "entry": {
        "media_type": "image",
        "label": "Image",
        "position": 1,
        "disabled": false,
        "types": [
            "image",
            "small_image",
            "thumbnail"
        ],
        "content": {
            "base64_encoded_data": YOU_NEED_YOUR_IMAGE_BASE64_ENCODED,
            "type": "image/png",
            "name": "choose_any_name.png"
        }
    }
}

After that your previously added product B201-SKU, will have the associated image.

3
  • You can also check the catalogProductAttributeMediaGalleryManagementV1 for further options and instructions in the Magento2 online Rest API documentation Commented Aug 11, 2017 at 9:57
  • 1
    Just heads up. When converting an image to base64 most online converters will put the meta-data at the beginning like data/jpeg. Everything before the comma needs to be stripped for Magento. Commented Oct 4, 2017 at 0:54
  • According to the docs, base64EncodedData should actually be base64_encoded_data. Commented Nov 25, 2017 at 9:19
2

For uploading and assigning images to products via API, there are two different scenarios:

A) each image is used for exactly one SKU
B) images can be used for multiple SKUs

In case A, things are simple, and @mfal 's answer in this post gives enough clues to get the job done:

Create a post to https://<magento>/rest/V1/products/<sku>/media (remember to url encode the sku) - with a body like this:

{
  "entry": {
    "media_type": "image",
    "label": "I am an image!",
    "types": [
      "image"
    ],
    "content": {
      {
        "base64_encoded_data": <base64 encoded file>,
        "type": "image/jpeg",
        "name": "<image filename>"
      }
    },
    "file": "<image filename>"
  }
}

... the image is uploaded to Magento, added to the table catalog_product_entity_media_gallery, and linked to the product. I have attached a python script for this type of request at the end of this answer.

Unfortunately, this happens with every call of the API: the picture is uploaded again and again. Magento2 detects that a file with the same name exists already and adds an incrementor to the file name (file.jpg, file_1.jpg, file_2.jpg, ...). Such an easy way to write the harddisk full!

This is, why in case B, things necessarily should get a bit more complex. Case B applies to situations where the script is to be executed multiple times, maybe for automation purposes. It also applies to situations where one picture is to be used for multiple skus, as in a clothes shop, where typically all sizes of the same product have different skus, but the same image.

The entry post to https://<magento>/rest/V1/products/<sku>/media is still a great starting point, but we need to check in advance, if the file exists on the server yet.

While it is quite easy to figure out which images are linked to a certain sku by using the API, I did not find a quick way to figure out if an image exists on the server. Therefore, an image uploading script might need to maintain a list of uploaded filenames. It could be based on the content of the table catalog_product_entity_media_gallery.

In cases where an image exists on the server already, we only need to assign it to the product / sku. This is done via a different API call. Assuming the product has been created already, the API call would go as a PUT request to https://magento/rest/V1/products/10000%2F100%2FS:

{
  "product": {
    "custom_attributes": {
      "image" : "<filename of the image in catalog_product_entity_media_gallery>",
      "thumbnail" : "<filename of the image in catalog_product_entity_media_gallery>",
      "small_image" : "<filename of the image in catalog_product_entity_media_gallery>"
    },
    "media_gallery_entries": [
      {
        "id": <value id of the image in catalog_product_entity_media_gallery> ,
        "media_type": "image",
        "label": "<choose an image label>",
        "position": 1,
        "disabled": true,
        "types": [
            "thumbnail"
        ],
        "file": "<filename of the image in catalog_product_entity_media_gallery>"
      }
    ]
  }
}

This assigns a picture, - exactly one picture to the product, and removes all other ones. We therefore need to ensure that we create one media_gallery_entry per existing image, before we send this API request.


Here is a python3 script that uploads one image to one sku; mainly for case A:

import requests
import base64
import urllib
from json import dumps

TOKEN='123123123123123123123123'
IMGFILENAME='my_image_file.jpg'
SKU='10000/100/S'
DOMAIN='https://my-magento-domain.com'

with open(IMGFILENAME, "rb") as image_file:
    b64_encoded_string = base64.b64encode(image_file.read()).decode("utf8")
raw_data = {'base64_encoded_data': b64_encoded_string, 'type': 'image/jpeg', 'name': IMGFILENAME}
json_data = dumps(raw_data, indent=2)

url = DOMAIN + '/rest/V1/products/' + urllib.parse.quote_plus(SKU) + '/media'

mystring = f'''
{{
  "entry": {{
    "media_type": "image",
    "label": "my image label",
    "types": [
      "image"
    ],
    "content": 
        {json_data}
    ,
    "file": "{IMGFILENAME}"
 }} 
}}
'''

headers = {'content-type': 'application/json', 'Authorization': 'Bearer ' + TOKEN}
response = requests.post(url, data=mystring, headers=headers)
print("Response:\n" + response.text + "\nRequest Headers:" + response.request.headers + "nResponse Headers:" + response.headers)
1
  • "Assuming the product has been created already, the API call would go as a PUT request to magento/rest/V1/products/10000%2F100%2FS" Are you sure? I am on Magento ver. 2.3.4 and I can't do that. If I delete a media entry from the JSON body -> it is deleted from the product. But if I add a media entry to the JSON body -> response code is 200 but the media entry is NOT added to the product! Could you please double check? Commented Apr 26, 2020 at 21:23
1

We need to add add these attributes: image, small_image and thumbnail to custom_attributes:

$productData = [
        "attribute_set_id"  => 4,
        "type_id": "simple",
        "sku": "B201-SKU",
        "name": "B201",
        "price": 25,
        "status": 1,
        "custom_attributes" => [
                ["attribute_code" => "description", "value" => "Heavy Duty Brake Cables"],
                ["attribute_code" => "meta_description", "value" => "Some describing text"],
                ["attribute_code" => "image", "value" => "/w/i/sample_1.jpg"],
                ["attribute_code" => "small_image", "value" => "/w/i/sample_2.jpg"],
                ["attribute_code" => "thumbnail", "value" => "/w/i/sample_2.jpg"]

            ]
    ];

Payload:

{
    "product": {
      "attribute_set_id": 4,
      "type_id": "simple",
      "sku": "B201-SKU",
      "name": "B201",
      "price": 25,
      "status": 1,
      "custom_attributes": {
        "description": "Heavy Duty Brake Cables",
        "meta_description": "Some describing text",
        "image" : "/w/i/sample_1.jpg",
        "small_image": "/w/i/sample_2.jpg",
        "thumbnail": "/w/i/sample_3.jpg"
      }
  }
}

Read more here.

9
  • I tried like this but the image is not uploaded. And why the path is /w/i/sample_1.jpg ? The image may be in my /home/images/ from here I want to upload to magento. or may be in base64. Commented Sep 20, 2016 at 6:50
  • We need to upload to Magento. These images are under pub/media/catalog/product. Commented Sep 20, 2016 at 7:23
  • How these images will be there before upload? Commented Sep 20, 2016 at 7:43
  • Like import process, we need to upload these images with the path under pub/media/catalog/product. Commented Sep 20, 2016 at 16:14
  • I want to upload images via rest api into magento but this is not doing that? Commented Sep 21, 2016 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.