Product Images
Manage images for your products. Each product supports up to 10 images in JPEG, PNG, or GIF format (max 10MB each).
Each image's url is a presigned link, valid for 10 minutes from when it's returned — not a permanent CDN URL. Re-fetch the product (expand=images) for a fresh one when you need it later. Use the reorder endpoint to control display priority.
POST
/products/{id}/images Upload a product image
Uploads an image to a product. Supports JPEG, PNG, and GIF (max 10MB). Maximum 10 images per product.
Send the image as multipart/form-data with the file in a field named file — there is no JSON, base64, or URL alternative.
Path parameters
NameTypeDescription
idrequired
stringProduct ID.
e.g.
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"Header parameters
NameTypeDescription
EPD-Version
stringAPI version override (format `YYYY-MM-DD`). If omitted, your account's pinned version or the latest version is used.
e.g.
"2026-02-11"Code samples
curl -X POST https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images \
-H "Authorization: Bearer epd_test_sk_xxxx" \
-H "EPD-Version: 2026-02-11" \
-F "file=@/path/to/photo.jpg" import { readFileSync } from 'fs';
const form = new FormData();
form.append('file', new Blob([readFileSync('./photo.jpg')]), 'photo.jpg');
const response = await fetch('https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images', {
method: 'POST',
headers: {
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
// Don't set Content-Type — fetch sets the multipart boundary automatically
},
body: form,
});
const image = await response.json();
console.log(image.url); // presigned URL, valid for 10 minutes import requests
with open('photo.jpg', 'rb') as f:
response = requests.post(
'https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images',
headers={
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
},
files={'file': ('photo.jpg', f, 'image/jpeg')},
)
image = response.json()
print(image['url']) # presigned URL, valid for 10 minutes $ch = curl_init('https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer epd_test_sk_xxxx',
'EPD-Version: 2026-02-11',
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('/path/to/photo.jpg', 'image/jpeg', 'photo.jpg'),
],
]);
$response = json_decode(curl_exec($ch), true);
echo $response['url']; // presigned URL, valid for 10 minutes Responses
201 Image uploaded.
FieldTypeDescription
idrequired
stringe.g.
"6ba7b816-9dad-11d1-80b4-00c04fd430c8"product_idrequired
stringe.g.
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"urlrequired
string (uri)Presigned URL, valid for 10 minutes from when this response was generated — not a permanent link. Re-fetch the product (`expand=images`) for a fresh URL when needed.
e.g.
"https://epd-uploads.s3.amazonaws.com/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/photo.jpg?X-Amz-Expires=600&X-Amz-Signature=abc123"orderrequired
integerDisplay order (0-based).
e.g.
0created_atrequired
string (date-time)e.g.
"2024-01-15T10:30:00.000Z" 400 Bad Request. The request was invalid or cannot be served.
FieldTypeDescription
errorrequired
objecttyperequired
enumThe type of error.
invalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorcoderequired
stringA short string identifying the specific error.
e.g.
"validation_error"messagerequired
stringA human-readable message providing details about the error.
e.g.
"Request validation failed"paramnullable
stringThe parameter that caused the error, if applicable.
e.g.
"email"request_id
stringUnique request identifier for debugging.
e.g.
"req_a1b2c3d4e5f67890abcdef0123456789"field_errors
array[object]Detailed field-level errors for validation failures.
404 Not Found. The requested resource doesn't exist.
FieldTypeDescription
errorrequired
objecttyperequired
enumThe type of error.
invalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorcoderequired
stringA short string identifying the specific error.
e.g.
"validation_error"messagerequired
stringA human-readable message providing details about the error.
e.g.
"Request validation failed"paramnullable
stringThe parameter that caused the error, if applicable.
e.g.
"email"request_id
stringUnique request identifier for debugging.
e.g.
"req_a1b2c3d4e5f67890abcdef0123456789"field_errors
array[object]Detailed field-level errors for validation failures.
DELETE
/products/{id}/images/{imageId} Delete a product image
Path parameters
NameTypeDescription
idrequired
stringProduct ID.
e.g.
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"imageIdrequired
stringImage ID.
e.g.
"6ba7b816-9dad-11d1-80b4-00c04fd430d0"Header parameters
NameTypeDescription
EPD-Version
stringAPI version override (format `YYYY-MM-DD`). If omitted, your account's pinned version or the latest version is used.
e.g.
"2026-02-11"Code samples
curl -X DELETE https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/6ba7b816-9dad-11d1-80b4-00c04fd430d0 \
-H "Authorization: Bearer epd_test_sk_xxxx" \
-H "EPD-Version: 2026-02-11" const response = await fetch('https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/6ba7b816-9dad-11d1-80b4-00c04fd430d0', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
},
});
const result = await response.json();
console.log(result.deleted); // true import requests
response = requests.delete(
'https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/6ba7b816-9dad-11d1-80b4-00c04fd430d0',
headers={
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
},
)
result = response.json()
print(result['deleted']) # True $ch = curl_init('https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/6ba7b816-9dad-11d1-80b4-00c04fd430d0');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer epd_test_sk_xxxx',
'EPD-Version: 2026-02-11',
],
]);
$response = json_decode(curl_exec($ch), true);
echo $response['deleted'] ? 'true' : 'false'; Responses
200 Image deleted.
FieldTypeDescription
idrequired
stringe.g.
"6ba7b816-9dad-11d1-80b4-00c04fd430c8"deletedrequired
truemessagerequired
stringe.g.
"Product image successfully deleted." 404 Not Found. The requested resource doesn't exist.
FieldTypeDescription
errorrequired
objecttyperequired
enumThe type of error.
invalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorcoderequired
stringA short string identifying the specific error.
e.g.
"validation_error"messagerequired
stringA human-readable message providing details about the error.
e.g.
"Request validation failed"paramnullable
stringThe parameter that caused the error, if applicable.
e.g.
"email"request_id
stringUnique request identifier for debugging.
e.g.
"req_a1b2c3d4e5f67890abcdef0123456789"field_errors
array[object]Detailed field-level errors for validation failures.
PATCH
/products/{id}/images/reorder Reorder product images
Updates the display order of images. Position in the array determines the order (first = 0).
Path parameters
NameTypeDescription
idrequired
stringe.g.
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"Header parameters
NameTypeDescription
EPD-Version
stringAPI version override (format `YYYY-MM-DD`). If omitted, your account's pinned version or the latest version is used.
e.g.
"2026-02-11"Request body required
FieldTypeDescription
image_idsrequired
array[string]Image IDs in desired display order.
e.g.
["6ba7b816-9dad-11d1-80b4-00c04fd430d3","6ba7b816-9dad-11d1-80b4-00c04fd430d4","6ba7b816-9dad-11d1-80b4-00c04fd430d5"]Code samples
curl -X PATCH https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/reorder \
-H "Authorization: Bearer epd_test_sk_xxxx" \
-H "Content-Type: application/json" \
-H "EPD-Version: 2026-02-11" \
-d '{
"image_ids": ["6ba7b816-9dad-11d1-80b4-00c04fd430d3", "6ba7b816-9dad-11d1-80b4-00c04fd430d4", "6ba7b816-9dad-11d1-80b4-00c04fd430d5"]
}' const response = await fetch('https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/reorder', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer epd_test_sk_xxxx',
'Content-Type': 'application/json',
'EPD-Version': '2026-02-11',
},
body: JSON.stringify({
image_ids: [
'6ba7b816-9dad-11d1-80b4-00c04fd430d3',
'6ba7b816-9dad-11d1-80b4-00c04fd430d4',
'6ba7b816-9dad-11d1-80b4-00c04fd430d5',
],
}),
});
const result = await response.json();
console.log(result.data); // [{ id: '...', order: 0 }, ...] import requests
response = requests.patch(
'https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/reorder',
headers={
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
},
json={
'image_ids': [
'6ba7b816-9dad-11d1-80b4-00c04fd430d3',
'6ba7b816-9dad-11d1-80b4-00c04fd430d4',
'6ba7b816-9dad-11d1-80b4-00c04fd430d5',
]
},
)
result = response.json()
print(result['data']) $ch = curl_init('https://api.epd.com/v1/products/6ba7b810-9dad-11d1-80b4-00c04fd430c8/images/reorder');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer epd_test_sk_xxxx',
'Content-Type: application/json',
'EPD-Version: 2026-02-11',
],
CURLOPT_POSTFIELDS => json_encode([
'image_ids' => [
'6ba7b816-9dad-11d1-80b4-00c04fd430d3',
'6ba7b816-9dad-11d1-80b4-00c04fd430d4',
'6ba7b816-9dad-11d1-80b4-00c04fd430d5',
],
]),
]);
$response = json_decode(curl_exec($ch), true);
print_r($response['data']); Responses
200 Images reordered.
FieldTypeDescription
data
array[object] 400 Bad Request. The request was invalid or cannot be served.
FieldTypeDescription
errorrequired
objecttyperequired
enumThe type of error.
invalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorcoderequired
stringA short string identifying the specific error.
e.g.
"validation_error"messagerequired
stringA human-readable message providing details about the error.
e.g.
"Request validation failed"paramnullable
stringThe parameter that caused the error, if applicable.
e.g.
"email"request_id
stringUnique request identifier for debugging.
e.g.
"req_a1b2c3d4e5f67890abcdef0123456789"field_errors
array[object]Detailed field-level errors for validation failures.
404 Not Found. The requested resource doesn't exist.
FieldTypeDescription
errorrequired
objecttyperequired
enumThe type of error.
invalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorcoderequired
stringA short string identifying the specific error.
e.g.
"validation_error"messagerequired
stringA human-readable message providing details about the error.
e.g.
"Request validation failed"paramnullable
stringThe parameter that caused the error, if applicable.
e.g.
"email"request_id
stringUnique request identifier for debugging.
e.g.
"req_a1b2c3d4e5f67890abcdef0123456789"field_errors
array[object]Detailed field-level errors for validation failures.