Skip to main content
SocialCutter

CMS and websites

Set the product image on BigCommerce with the v3 API

Add a product image on BigCommerce with the v3 Catalog API using the URL SocialCutter returns and mark it as the main one. curl and Python.

  • BigCommerce
  • Catalog API
  • product image
  • API v3
  • image_url
  • is_thumbnail
  • OAuth scopes
  • Python

Why generate the sizes before uploading

A product image shows up in the catalogue grid, on the product page, in the cart line and in the social posts that promote the product. Each slot wants a different ratio, and uploading one copy per slot leaves the catalogue full of near-identical files.

The flow is: one master goes in, SocialCutter returns one output per destination, and BigCommerce receives the right one in each slot. The cover fit mode (the default) is a centred crop: it scales the image and splits the excess evenly on both sides. There is no subject detection and no automatic step that decides what to crop.

Use in BigCommerceSocialCutter destinationSize
Product main imageinstagram post1080x1080 (1:1)
Second product imageinstagram story1080x1920 (9:16)
Category bannerfacebook post1200x630 (1.91:1)
Store headertwitter header1500x500 (3:1)
Product video thumbnailyoutube thumbnail1280x720 (16:9)

The full catalogue comes from GET /api/v1/platforms, which is public, and is summarised in the social media sizes guide.

Note: there is no 4:5 in the SocialCutter catalogue. Vertical is 9:16 (1080x1920) and square is 1:1 (1080x1080). Use 1:1 as the main image; if you need an exact 4:5, crop outside SocialCutter.

Before you start: credential and scopes

A BigCommerce API account is created in the control panel under Settings → API → API accounts. You pick the scope as you create it. Since every request in this guide hits the Catalog API v3, you need the products scope:

ScopeWhat you need it for here
store_v2_productsCreating and updating product images
store_v2_products_read_onlyOnly if you just read the catalogue

Scopes are granted when the credential is created and are not widened per request: if one is missing, regenerate the account. The current list and names live at https://developer.bigcommerce.com/docs/start/authentication/api-accounts — check it, because BigCommerce has been consolidating endpoints under a shared products scope.

Authentication uses two headers: X-Auth-Token with the access token and Accept: application/json. The store hash goes in the path:

export BC_STORE="your_store_hash"
export BC_TOKEN="your_access_token"
export SC_KEY="sc_your_key"
export BC_API="https://api.bigcommerce.com/stores/$BC_STORE/v3"
curl -s "$BC_API/catalog/products?limit=1" \
  -H "X-Auth-Token: $BC_TOKEN" \
  -H "Accept: application/json" | jq '.data[0] | {id, name}'

1. Process the master with SocialCutter

curl -s -X POST "https://api.socialcutter.theboomer.dev/api/v1/images/process" \
  -H "X-API-Key: *** \
  -H "Content-Type: application/json" \
  -d '{
    "source": { "type": "url", "value": "https://your-cdn.com/master.jpg" },
    "destinations": [
      { "platform": "instagram", "format": "post" },
      { "platform": "instagram", "format": "story" }
    ]
  }' > sc.json

jq '.image_id, (.outputs[] | {url, platform, format, width, height})' sc.json

Each output is a public URL. BigCommerce accepts URLs when creating an image, so there is nothing to download.

2. Create the product image

The creation endpoint lives under the product and takes one image per request. It has two mutually exclusive modes:

  • image_url in JSON: you pass the SocialCutter URL and BigCommerce fetches it.
  • image_file in multipart: you upload the binary. The header must then be multipart/form-data.
MAIN_URL=$(jq -r '.outputs[] | select(.platform=="instagram" and .format=="post") | .url' sc.json)

curl -s -X POST "$BC_API/catalog/products/123/images" \
  -H "X-Auth-Token: $BC_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{\"image_url\": \"$MAIN_URL\", \"is_thumbnail\": true, \"description\": \"Front view 1:1\"}" \
  > image.json

jq '.data | {id, is_thumbnail, url_standard, url_thumbnail}' image.json

With is_thumbnail: true at creation the image is born as the main one. description is the alt text the storefront uses.

Reference: https://developer.bigcommerce.com/docs/store-operations/catalog

3. Python variant and multipart variant

With requests the flow is the same. The JSON goes through json= and the multipart through files=; mixing image_url with image_file is an error.

import os
import requests

SC_KEY = os.environ["SC_KEY"]
BC_API = f'https://api.bigcommerce.com/stores/{os.environ["BC_STORE"]}/v3'
BC_HEADERS = {
    "X-Auth-Token": os.environ["BC_TOKEN"],
    "Accept": "application/json",
}

sc = requests.post(
    "https://api.socialcutter.theboomer.dev/api/v1/images/process",
    headers={"X-API-Key": SC_KEY, "Content-Type": "application/json"},
    json={
        "source": {"type": "url", "value": "https://your-cdn.com/master.jpg"},
        "destinations": [{"platform": "instagram", "format": "post"}],
    },
    timeout=30,
)
sc.raise_for_status()
main_url = sc.json()["outputs"][0]["url"]

product_id = 123
created = requests.post(
    f"{BC_API}/catalog/products/{product_id}/images",
    headers=BC_HEADERS,
    json={"image_url": main_url, "is_thumbnail": True, "description": "Front view 1:1"},
    timeout=30,
)
created.raise_for_status()
image = created.json()["data"]
print(image["id"], image["is_thumbnail"], image["url_standard"])

# Multipart variant, when the image only exists on disk:
with open("story.jpg", "rb") as fh:
    up = requests.post(
        f"{BC_API}/catalog/products/{product_id}/images",
        headers=BC_HEADERS,          # requests sets the multipart Content-Type itself
        files={"image_file": ("story.jpg", fh, "image/jpeg")},
        data={"is_thumbnail": "false"},
        timeout=60,
    )
up.raise_for_status()

Form fields carry no types: is_thumbnail travels as the string "false" or "true".

4. Changing the main image afterwards

If the image already exists and you want it promoted to main, update it by its id. A product can only have one thumbnail at a time, so the previous one stops being it implicitly.

IMAGE_ID=$(jq -r '.data.id' image.json)

curl -s -X PUT "$BC_API/catalog/products/123/images/$IMAGE_ID" \
  -H "X-Auth-Token: $BC_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"is_thumbnail": true}' | jq '.data.is_thumbnail'

To change the order the images are shown in, use sort_order (higher numbers lose priority). Endpoint reference: https://developer.bigcommerce.com/docs/store-operations/catalog

Cost

  • 1 use per destination (platform and format) per request; duplicates are not charged twice.
  • Failed processings are refunded.
  • Plans 0/3/9/29 EUR, all with API and MCP.

Common errors

SymptomCauseFix
401 from BigCommerceAccess token missing or from another storeCheck X-Auth-Token and that the store hash in the path is the right one
403 from BigCommerceThe credential lacks the products scopeRegenerate the API account with store_v2_products
422 with image_urlThe URL is not public, exceeds 255 characters, or the format is unsupportedPass the SocialCutter URL and use JPEG, PNG, GIF, WEBP, BMP, WBMP or XBM
413/image rejectedThe file is over 8 MBGenerate a smaller master with SocialCutter and retry
400 when sending both fieldsimage_url and image_file were sent togetherPick one: JSON with a URL or multipart with a file
413 from SocialCutterThe master is over 5 MBShrink the master before processing it

No code and next steps

An automation tool chains the same steps with nodes: a trigger, an HTTP node to /api/v1/images/process and an HTTP node to the Catalog API with the output URL. The general pattern is in the automating social media images guide.

Frequently asked questions

Can I hand BigCommerce the URL SocialCutter returns?

Yes. The image creation endpoint accepts image_url in a JSON request, so the SocialCutter output can be passed straight through without downloading and re-uploading it. If you would rather send the binary, there is a multipart variant with the image_file field.

How do I mark the image as the main one?

With the is_thumbnail field set to true. You can include it in the creation body, or update an existing image with PUT to that image's endpoint. A product can only have one thumbnail at a time, and if it has a single image that image acts as both the main image and the thumbnail.

Which scopes does the credential need?

The products scope of the API account (store_v2_products; store_v2_products_read_only if you only read). It is granted when the API account is created and cannot be widened per request: if it is missing, regenerate the credential with the scope ticked.

What is the size limit and which formats are accepted?

8 MB per image, both by URL and by file upload, and one file per request. The types BigCommerce documents are BMP, GIF, JPEG, PNG, WBMP, XBM and WEBP.

What does it cost to process one product image?

1 use per destination, meaning per platform and format pair. Instagram post and Instagram story from the same master spend 2 uses.