---
title: "Add pictures to a product"
method: POST
path: "/products/{id}/images"
tags: ["products"]
---

# Add pictures to a product

`POST /products/{id}/images`

## Request

- Base URL: `https://0.0.0.0:3000/api/v1`
- URL: `https://0.0.0.0:3000/api/v1/products/{id}/images`
- Auth: API key in header `x-api-key`

Adds pictures to a product's gallery without resending the rest — what a catalogue sync, or a workshop's own tooling, calls to keep product photos current. Admin keys only: the key's owner must be allowed to manage products, and a seller key gets 403.

The body is `multipart/form-data`. Send each picture as a `file` part (PNG, JPG or WEBP, 50 MB at most) or as a `url` field, which we download and store. A link to someone else's server is never saved as it is, because the catalogue goes blank the day that server stops answering. Up to 10 pictures per request: repeat the part to send several, in the order they should appear.

New pictures join the end of the gallery, which holds 20. `as_cover=true` makes the first one the product's cover, and the old cover moves into the gallery rather than being lost; a product with no cover gets the first picture as its cover anyway.

If any picture is refused — a link that is not a reachable image, a file that is not one — the answer is 422, naming it in `message` with the cause in `reason`, and nothing is added. A gallery with no room left answers 409.

## Path parameters

- `id` integer, required

## Headers

- `Idempotency-Key` string

## Response `200`

The product's cover and full gallery after the upload. `meta.added` lists the stored URLs of the new pictures.

## Other responses

- `401`: No key, or a key that is unknown, revoked or expired. One message for all four — telling you which would confirm to a guesser that a key exists.
- `403`: The key is valid but its owner may not do this.
- `404`: No such record — including records that exist but belong to someone else. The API never confirms another seller's ids.
- `409`: The request contradicts the current state of the record.
- `413`: The request body is over the limit: 2 MB for a JSON body, 50 MB for a proof photo.
- `422`: The body or query is malformed. Field-level detail arrives in `error.fields`.
- `429`: Over the per-key limit. `Retry-After` says how many seconds to wait.
- `500`: Our fault. `error.request_id` matches the X-Request-Id header — quote it to support.

---

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