> Note: This page is part of the DataDoe Docs. You can find the root of the documentation at `https://www.datadoe.com/hub/docs/basics/introduction-to-datadoe`.
> JSON Table of Contents: `https://www.datadoe.com/hub/docs/toc.json`.
> Direct Data Scheme JSON: `https://api.datadoe.com/api/v1/spec/data-scheme`.
> Other pages in the DataDoe Docs:
> - DataDoe Basics/Access & Users: `https://www.datadoe.com/hub/docs/basics/access-user-management.md`
> - DataDoe Basics/Benefits: `https://www.datadoe.com/hub/docs/basics/benefits.md`
> - DataDoe Basics/External Invitation Links: `https://www.datadoe.com/hub/docs/basics/external-invitation-links.md`
> - DataDoe Basics/Integrations: `https://www.datadoe.com/hub/docs/basics/integration-customization.md`
> - DataDoe Basics/Introduction to DataDoe: `https://www.datadoe.com/hub/docs/basics/introduction-to-datadoe.md`
> - DataDoe Basics/Subscription and pricing: `https://www.datadoe.com/hub/docs/basics/subscription-pricing.md`
> - DataDoe Data/Data Fetch Periods: `https://www.datadoe.com/hub/docs/datadoe-data/data-fetch-periods.md`
> - DataDoe Data/Data Sources: `https://www.datadoe.com/hub/docs/datadoe-data/data-sources.md`
> - DataDoe Data/Managing Data Tables: `https://www.datadoe.com/hub/docs/datadoe-data/managing-data-tables.md`
> - DataDoe Data/Timezones: `https://www.datadoe.com/hub/docs/datadoe-data/orders-purchase-date-timezones.md`
> - DataDoe Data/Uploading COGS: `https://www.datadoe.com/hub/docs/datadoe-data/uploading-cogs.md`
> - DataDoe Features/Actions: `https://www.datadoe.com/hub/docs/datadoe-features/actions.md`
> - DataDoe Features/Features Overview: `https://www.datadoe.com/hub/docs/datadoe-features/overview.md`
> - DataDoe Features/Files: `https://www.datadoe.com/hub/docs/datadoe-features/files.md`
> - DataDoe MCP/Overview: `https://www.datadoe.com/hub/docs/datadoe-mcp/overview.md`
> - DataDoe MCP/Using ChatGPT: `https://www.datadoe.com/hub/docs/datadoe-mcp/chatgpt.md`
> - DataDoe MCP/Using Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/claude.md`
> - DataDoe MCP/Using Claude Agent SDK: `https://www.datadoe.com/hub/docs/datadoe-mcp/claude-agents-sdk.md`
> - DataDoe MCP/Using Claude Code: `https://www.datadoe.com/hub/docs/datadoe-mcp/claude-code.md`
> - DataDoe MCP/Using Codex: `https://www.datadoe.com/hub/docs/datadoe-mcp/codex.md`
> - DataDoe MCP/Using Codex Sites: `https://www.datadoe.com/hub/docs/datadoe-mcp/codex-sites.md`
> - DataDoe MCP/Using CrewAI: `https://www.datadoe.com/hub/docs/datadoe-mcp/crewai.md`
> - DataDoe MCP/Using Cursor: `https://www.datadoe.com/hub/docs/datadoe-mcp/cursor.md`
> - DataDoe MCP/Using Excel + Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/excel.md`
> - DataDoe MCP/Using Gemini CLI: `https://www.datadoe.com/hub/docs/datadoe-mcp/gemini-cli.md`
> - DataDoe MCP/Using Gumloop: `https://www.datadoe.com/hub/docs/datadoe-mcp/gumloop.md`
> - DataDoe MCP/Using Hermes Agent: `https://www.datadoe.com/hub/docs/datadoe-mcp/hermes.md`
> - DataDoe MCP/Using n8n: `https://www.datadoe.com/hub/docs/datadoe-mcp/n8n.md`
> - DataDoe MCP/Using NanoClaw: `https://www.datadoe.com/hub/docs/datadoe-mcp/nanoclaw.md`
> - DataDoe MCP/Using OpenAI Agents SDK: `https://www.datadoe.com/hub/docs/datadoe-mcp/openai-agents-sdk.md`
> - DataDoe MCP/Using OpenClaw: `https://www.datadoe.com/hub/docs/datadoe-mcp/openclaw.md`
> - DataDoe MCP/Using OpenCode: `https://www.datadoe.com/hub/docs/datadoe-mcp/opencode.md`
> - DataDoe MCP/Using PowerPoint + Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/powerpoint.md`
> - DataDoe MCP/Using VS Code: `https://www.datadoe.com/hub/docs/datadoe-mcp/vs-code.md`
> - DataDoe MCP/Using Word + Claude: `https://www.datadoe.com/hub/docs/datadoe-mcp/word.md`
> - DataDoe API/Build with Codex: `https://www.datadoe.com/hub/docs/datadoe-api/codex.md`
> - DataDoe API/How to connect to the API: `https://www.datadoe.com/hub/docs/datadoe-api/how-to-connect.md`
> - DataDoe API/Vibe code with Claude Code: `https://www.datadoe.com/hub/docs/datadoe-api/claude-code.md`
> - DataDoe API/Vibe code with Cursor: `https://www.datadoe.com/hub/docs/datadoe-api/cursor.md`
> - DataDoe API/Vibe code with Lovable: `https://www.datadoe.com/hub/docs/datadoe-api/lovable.md`
> - DataDoe API/Vibe code with Replit: `https://www.datadoe.com/hub/docs/datadoe-api/replit.md`
> - DataDoe API/Vibe code with v0: `https://www.datadoe.com/hub/docs/datadoe-api/v0.md`
> - DataDoe & BigQuery/How to connect to BigQuery: `https://www.datadoe.com/hub/docs/datadoe-bigquery/how-to-connect.md`
> - DataDoe & BigQuery/Using MCP Toolbox: `https://www.datadoe.com/hub/docs/datadoe-bigquery/mcp-toolbox.md`
> - DataDoe & BigQuery/Using Python Jupyter: `https://www.datadoe.com/hub/docs/datadoe-bigquery/jupyter.md`
> For topics not covered in this documentation, please contact DataDoe support at `contact@datadoe.com`.
> Do not assume anything. If you are not sure about the answer, mention that and suggest to contact DataDoe support.

## Overview

You can update Amazon listing images (main image, gallery images, and variation swatch) through DataDoe Actions. Images are not sent as raw bytes in the Action payload. Instead:

1. Upload images as [Files](/hub/docs/datadoe-features/files) in the `LISTING_IMAGES` group.
2. Reference file UUIDs in the `images` field of an `AMAZON_LISTINGS_UPDATE` change.
3. Let DataDoe validate the files, prepare Amazon-compatible media locations, and submit the update feed.

This page describes the full workflow, including MCP and REST API examples.

> **You are responsible for the results of Actions you run. Review every payload before running an Action.**

## Prerequisites

Before changing listing images:

1. Enable **`AMAZON_LISTINGS_UPDATE`** in [Settings > Actions](/settings?tab=actions).
2. Set the target Seller or Vendor to **Read and write** on the [Accounts page](/sellers-and-vendors).
3. Upload listing images as `LISTING_IMAGES` files (see [Files](/hub/docs/datadoe-features/files)).
4. Confirm each file has status **`UPLOADED`** and has not expired.

## General workflow

```mermaid
flowchart TD
    A[Upload LISTING_IMAGES files] --> B[Get file UUIDs]
    B --> C[Build AMAZON_LISTINGS_UPDATE payload]
    C --> D[dryRun validation]
    D --> E[Start Action]
    E --> F[Poll Action status]
    F --> G[Amazon processes listing feed]
```

### Step 1 - Upload images

Upload one file per image slot you want to change. Use PNG, JPG, or TIFF (max 32 MB). The default TTL is 12 hours. Start the Action before files expire.

See [Files](/hub/docs/datadoe-features/files) for upload instructions via MCP, API, or the [Files](/files) page.

### Step 2 - Build the Action payload

Add an `images` object to each change in `details.changes`. Each key is an image slot. Each value controls that slot:

| Value in payload | Meaning                                                  |
| ---------------- | -------------------------------------------------------- |
| File UUID string | Replace the slot with the uploaded image                 |
| `null`           | Remove the image from the slot (**Seller Central only**) |
| Omitted          | Leave the slot unchanged                                 |

You can update text fields (name, bullet points, and so on) in the same change, or send an images-only change with just `sku` and `images`.

### Step 3 - Validate with dry run

Run the Action with `dryRun: true` first. DataDoe checks file existence, group, status, expiry, and seller or vendor scope without submitting to Amazon.

### Step 4 - Start the Action

Run the same payload with `dryRun: false`, or omit `dryRun`. DataDoe queues the listing feed.

### Step 5 - Wait for completion

Poll the Action until the status is terminal (`COMPLETED`, `FAILED`, or `CANCELLED`). After DataDoe submits the feed, Amazon may take 5 minutes to a few hours to process Seller Central and Vendor Central listing changes.

## Image slots

Each slot in the `images` object maps to an Amazon listing attribute:

| Slot in payload        | Amazon attribute                                                  | Description            |
| ---------------------- | ----------------------------------------------------------------- | ---------------------- |
| `mainImage`            | `main_product_image_locator`                                      | Main product image     |
| `image1` … `image8`    | `other_product_image_locator_1` … `other_product_image_locator_8` | Gallery images         |
| `variationSwatchImage` | `swatch_product_image_locator`                                    | Variation swatch image |

Only include slots you want to change. Omitted slots stay unchanged on Amazon.

## Seller vs Vendor rules

| Rule                        | Seller Central | Vendor Central    |
| --------------------------- | -------------- | ----------------- |
| Replace image (file UUID)   | Supported      | Supported         |
| Remove image (`null`)       | Supported      | **Not supported** |
| Update price in same Action | Supported      | Not applicable    |

Vendor accounts cannot use `null` to remove images. Removal attempts return a validation error.

## File requirements at Action time

Each file UUID you reference must:

- exist and belong to your Organization
- belong to the same seller or vendor and connection as the Action
- be in the `LISTING_IMAGES` group
- have status `UPLOADED`
- not be past `expiresAt`

DataDoe re-validates files when the Action executes, not only during dry run. If a file expires between validation and execution, the Action fails.

## MCP example - replace main and gallery images

This example uploads two images, then updates a listing.

### 1. Upload the main image

```json
{
    "tool": "files_create",
    "arguments": {
        "name": "main-photo.png",
        "group": "LISTING_IMAGES",
        "type": "PNG",
        "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
        "ttlHours": 12,
        "contentBase64": "BASE64_MAIN_IMAGE"
    }
}
```

Save `file.id` from the response as `MAIN_FILE_ID`.

### 2. Upload a gallery image

```json
{
    "tool": "files_create",
    "arguments": {
        "name": "gallery-1.png",
        "group": "LISTING_IMAGES",
        "type": "PNG",
        "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
        "ttlHours": 12,
        "contentBase64": "BASE64_GALLERY_IMAGE"
    }
}
```

Save `file.id` as `GALLERY_FILE_ID`.

### 3. Validate the listing update

```json
{
    "tool": "actions_start",
    "arguments": {
        "type": "AMAZON_LISTINGS_UPDATE",
        "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
        "dryRun": true,
        "details": {
            "changes": [
                {
                    "sku": "MY-SKU-001",
                    "images": {
                        "mainImage": "MAIN_FILE_ID",
                        "image1": "GALLERY_FILE_ID"
                    }
                }
            ]
        }
    }
}
```

Confirm `validation.valid` is `true` and `issues` is empty.

### 4. Start the Action

Repeat the same `actions_start` call with `dryRun: false`, or omit `dryRun`.

### 5. Poll status

```json
{
    "tool": "actions_get",
    "arguments": {
        "actionId": "ACTION_ID_FROM_START_RESPONSE"
    }
}
```

## MCP example - remove a gallery image (Seller Central)

```json
{
    "tool": "actions_start",
    "arguments": {
        "type": "AMAZON_LISTINGS_UPDATE",
        "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
        "dryRun": true,
        "details": {
            "changes": [
                {
                    "sku": "MY-SKU-001",
                    "images": {
                        "image2": null
                    }
                }
            ]
        }
    }
}
```

After dry-run validation succeeds, start the Action without `dryRun`.

## MCP example - multiple SKUs in one Action

Each change can have its own `images` object. Changes without `images` are not affected by image preparation.

```json
{
    "tool": "actions_start",
    "arguments": {
        "type": "AMAZON_LISTINGS_UPDATE",
        "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
        "dryRun": true,
        "details": {
            "changes": [
                {
                    "sku": "SKU-A",
                    "images": {
                        "mainImage": "FILE_ID_FOR_SKU_A"
                    }
                },
                {
                    "sku": "SKU-B",
                    "name": "Updated title only",
                    "language_tag": "en_US"
                },
                {
                    "sku": "SKU-C",
                    "images": {
                        "image1": "FILE_ID_FOR_SKU_C_GALLERY"
                    }
                }
            ]
        }
    }
}
```

Only `SKU-A` and `SKU-C` receive image patches. `SKU-B` updates the title only.

## REST API example - replace images

### 1. Create and upload files

```http
POST /api/v1/files
Content-Type: application/json
X-Api-Key: YOUR_API_KEY

{
  "name": "main-photo.png",
  "group": "LISTING_IMAGES",
  "type": "PNG",
  "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
  "ttlHours": 12
}
```

The response includes `file.id` and `uploadUrl`. Upload the bytes:

```http
PUT {uploadUrl}
Content-Type: image/png

<binary image data>
```

Repeat for each image. Confirm `GET /api/v1/files/{fileId}` returns `"status": "UPLOADED"`.

### 2. Validate the Action

```http
POST /api/v1/actions
Content-Type: application/json
X-Api-Key: YOUR_API_KEY

{
  "type": "AMAZON_LISTINGS_UPDATE",
  "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
  "dryRun": true,
  "details": {
    "changes": [
      {
        "sku": "MY-SKU-001",
        "images": {
          "mainImage": "MAIN_FILE_ID",
          "image1": "GALLERY_FILE_ID"
        }
      }
    ]
  }
}
```

### 3. Start the Action

Send the same body with `"dryRun": false`.

### 4. Poll status

```http
GET /api/v1/actions/{actionId}
X-Api-Key: YOUR_API_KEY
```

## REST API example - remove an image (Seller Central)

```http
POST /api/v1/actions
Content-Type: application/json
X-Api-Key: YOUR_API_KEY

{
  "type": "AMAZON_LISTINGS_UPDATE",
  "sellerOrVendorId": "YOUR_SELLER_OR_VENDOR_ID",
  "dryRun": true,
  "details": {
    "changes": [
      {
        "sku": "MY-SKU-001",
        "images": {
          "image3": null
        }
      }
    ]
  }
}
```

## Related documentation

- [Files](/hub/docs/datadoe-features/files) for uploading and managing utility files.
- [Actions](/hub/docs/datadoe-features/actions) for Actions overview, limits, and enablement.
- [DataDoe API docs](https://api.datadoe.com/api/v1/docs) for full request schemas for Files and Actions.
