For AI agents: markdown of this page — /docs-content-en/entities/catalog-products/images.md documentation index — /llms.txt

Product images

Reads, uploads and deletes images for a catalog product. All routes require an API key with the catalog scope; uploads and deletes require a write-enabled key.

The methods return only the product's native images: its detail picture, preview picture, and MORE_PHOTO gallery items. Files stored in other custom File properties (propertyNNN) are not included.

These routes use the shared product ID space for simple products, SKUs, variations and services.

Bitrix24 API: catalog.productImage.list, catalog.productImage.get, catalog.productImage.add, catalog.productImage.delete Scope: catalog

Safe handling of the image address

Treat detailUrl as untrusted input. The API validates only the URL shape and returns it without normalization. Do not make a server-side HTTP request to this address: doing so creates a server-side request forgery (SSRF) risk. A path beginning with / is relative to the Bitrix24 account origin. For a user interface, pass the address to a safe client-side component instead of downloading it through your backend.

The downloadUrl download link is not included in the response because it may contain a webhook path and secret. The API neither proxies nor downloads the file. A detailUrl containing a webhook path is also rejected.

Upload product image

POST /v1/catalog-products/:productId/images

Uploads a catalog product image from base64 content: a detail picture, a preview picture or a gallery image. The request body is flat JSON.

Parameters

Parameter Type Required Description
productId (path) number yes Product ID. List: GET /v1/catalog-products. The ID of an SKU from GET /v1/catalog-skus, an offer from GET /v1/catalog-offers or a service from GET /v1/catalog-services also works

Request fields (body)

Field Type Required Description
type string yes Image type: DETAIL_PICTURE — detail picture, PREVIEW_PICTURE — preview picture, MORE_PHOTO — gallery image. Any other value is rejected before calling Bitrix24
fileName string yes File name with an extension, for example photo.png. An empty name is rejected
fileContent string yes File content in base64

The body accepts no other fields: an extra field such as description returns 400 INVALID_PARAMS. The request body limit is 40 MiB.

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/catalog-products/7257/images" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "MORE_PHOTO",
    "fileName": "photo.png",
    "fileContent": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL/nwAAAABJRU5ErkJggg=="
  }'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/catalog-products/7257/images" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "MORE_PHOTO",
    "fileName": "photo.png",
    "fileContent": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL/nwAAAABJRU5ErkJggg=="
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/catalog-products/7257/images', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    type: 'MORE_PHOTO',
    fileName: 'photo.png',
    fileContent: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL/nwAAAABJRU5ErkJggg==',
  }),
})

const { success, data } = await res.json()
console.log('Image ID:', data.id)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/catalog-products/7257/images', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    type: 'MORE_PHOTO',
    fileName: 'photo.png',
    fileContent: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4z8DwHwAFgAI/ScL/nwAAAABJRU5ErkJggg==',
  }),
})

const { success, data } = await res.json()

Response fields

A successful upload responds with HTTP status 201 Created.

Field Type Description
success boolean Always true on success
data object Uploaded image
data.id number Image ID
data.productId number ID of the product that owns the image
data.type string Image type: DETAIL_PICTURE — detail picture, PREVIEW_PICTURE — preview picture, MORE_PHOTO — gallery image
data.name string File name
data.createTime string | null Creation time in ISO 8601 format with a UTC offset, or null
data.detailUrl string Image address — a path starting with / relative to the Bitrix24 account origin, or an absolute http/https URL. Access without a Bitrix24 account session is not guaranteed. Treat it as untrusted input — see Product images

Response example

JSON
{
  "success": true,
  "data": {
    "id": 38993,
    "productId": 7257,
    "type": "MORE_PHOTO",
    "name": "photo.png",
    "createTime": "2026-10-08T20:59:02+00:00",
    "detailUrl": "https://cdn.bitrix24.com/b00000000/iblock/2ba/2bae996b883855a3997fde84f01c7aee/photo.png"
  }
}

Error response example

400 — an unknown type, an empty file name, content that is not base64, or an extra body field:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "type, fileName and base64 fileContent are required"
  }
}

Errors

HTTP Code Description
400 INVALID_PARAMS The body failed validation: an unknown type, an empty or missing fileName, fileContent that is not base64, or another field in the body
400 INVALID_PARAMS productId is not a canonical positive integer — for example, abc, 0 or a value outside the JavaScript safe integer range
404 ENTITY_NOT_FOUND No product with this productId exists
413 PAYLOAD_TOO_LARGE The request body exceeds 40 MiB
422 BITRIX_ERROR Bitrix24 did not accept the file, for example a name with a non-image extension such as note.txt
422 BITRIX_ERROR The new image was not saved: replacing DETAIL_PICTURE or PREVIEW_PICTURE left the previous picture in place. The message is Product image was not saved
502 BITRIX_UNAVAILABLE Bitrix24 is unavailable or returned a response that failed the shape and safety checks
401 MISSING_API_KEY The X-Api-Key header is missing
401 INVALID_API_KEY The key is invalid
401 TOKEN_MISSING The key has no Bitrix24 tokens
403 SCOPE_DENIED The key does not have the catalog scope
403 WRITE_BLOCKED_READONLY_KEY The key is read-only. Uploads and deletes require a write-enabled key
403 BITRIX_ACCESS_DENIED Bitrix24 denied access to the catalog
429 RATE_LIMITED The request limit was reached. Retry after the time in the Retry-After header
429 OPERATION_TIME_LIMIT The Bitrix24 operation-time limit was reached. Retry after the time in the Retry-After header
503 BITRIX_TIMEOUT Bitrix24 did not respond in time, so the write outcome is unknown. Check the product image list before retrying

Full list of common API errors — Errors.

Known specifics

  • Replacing the detail and preview pictures. A product has one detail picture and one preview picture. Uploading DETAIL_PICTURE or PREVIEW_PICTURE again replaces the previous one: the response carries a new id, and the previous id can no longer be read. MORE_PHOTO adds a picture to the gallery.
  • File content is not checked. Text uploaded as photo.png is saved as a picture. Make sure fileContent is an image before uploading.
  • Identical content shares one file. Uploading the same content again creates an image with a new id, but its name and detailUrl come from the earlier file, even if fileName carries a different name.

See also