---
title: "Associate images with a product"
method: POST
path: "/public/v1/products/{id}/images"
tags: ["Product"]
---

# Associate images with a product

`POST /public/v1/products/{id}/images`

Replaces the full set of images on a product with images Distru already hosts. Each URL must be the `url` of an existing product image, as [GET /public/v1/products/{id}](#get-a-product) returns it, from this product or another one. Distru copies each image and attaches the copy to the product. Any other URL is rejected with a 400. To add a new image, upload the file with [POST /public/v1/product-images](#upload-a-product-image).

This is a full replacement, not an append: the product's existing images are removed and replaced by exactly what you send. Send an empty array to remove all images; omitting `image_urls` does the same. The order of the array is the display order: the first URL becomes the product's primary image, and product responses list images in that order. At most 4 URLs are accepted. The operation is all-or-nothing: if any URL is rejected or fails to copy, no images are changed and the response is a 400 with a single human-readable error message.

This affects only the product's images, and updates the product's `updated_datetime`; it does not touch inventory or push anything to Metrc or BioTrack. On success the response is 204 with no body; re-fetch the product to see the new image URLs.

Required permission: `products_permissions_edit` (plus access to the product under team restrictions).

## Path parameters

- `id` string, required

## Request body

- UpsertProductImagesRequest
  - `image_urls` string[] — URLs of existing Distru product images, in display order (first = primary image). At most 4. An empty array, or omitting the field, removes every image from the product.

## Response `204`

Images updated successfully

## Other responses

- `400` — Invalid parameters
- `401` — Missing or invalid API token
- `403` — The API token lacks the required permission
- `404` — Not Found

## Changes

- **2026-10-07** `e8639f7dafed` — 1 breaking, 1 info
  - the request's body type changed from `array` to `object`
  - added the new optional request property `image_urls`

[Change history](https://skmtc.dev/distru/apis/distru-api/changes/public/v1/products/:id/images/post.md)

---

[API](https://skmtc.dev/distru/apis/distru-api.md) · [All operations](https://skmtc.dev/distru/apis/distru-api/llms.txt) · [OpenAPI document](https://skmtc.dev/distru/apis/distru-api/revisions/e8639f7dafed?raw)
