# Image library

> Upload, resize, and manage up to 300 PNG, JPG, or WebP images with the Moov images API or Dashboard, and link them to products in your product catalog.

> AI agents: search and read all Moov docs with the docs MCP server at https://docs.moov.io/mcp (no API key). Setup: https://docs.moov.io/guides/developer-tools/mcp-ai/docs-mcp/index.md

Upload and store images with Moov to create an image library. Link images to products in your product catalog.

Use the [images API](/api/tools/images/index.md) to upload an image up to 16MB in PNG, JPG, or WebP format. Every image will be given a unique `imageID`, which can be linked to products in your product catalog, enhancing your transfer UI. Each Moov account has a starting limit of 300 images.

View the [product catalog](/guides/account-tools/product-catalog/index.md) guide for more information on how to use images with products.

## Upload image

In addition to the image itself, you can supply alt-text through the `metadata` field. Duplicate images and images larger than 16MB will be rejected.

**cURL**

```zsh
curl -X POST "https://api.moov.io/accounts/{accountID}/images" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00" \
  --data '{
    "image": "00010101011111000101010110",
    "metadata": {
      "altText": "Blue oat milk carton by Fancy Brand"
    }
  }'
```

**TypeScript**

```typescript
const result = await moov.images.upload({
  accountID: "c0971a52-1f1c-4511-876a-f45c4cfd6154",
  imageUploadRequestMultiPart: {
    image: await openAsBlob("example.file"),
  },
});
```

**Python**

```python
res = moov.images.upload(account_id="c0971a52-1f1c-4511-876a-f45c4cfd6154", image={
    "file_name": "example.file",
    "content": open("example.file", "rb"),
})
```

**Ruby**

```ruby
res = s.images.upload(account_id: 'c0971a52-1f1c-4511-876a-f45c4cfd6154', image_upload_request_multi_part: Models::Components::ImageUploadRequestMultiPart.new(
  image: Models::Components::Image.new(
    file_name: 'example.file',
    content: File.binread('example.file')
  )
))
```

**Java**

```java
        UploadImageResponse res = sdk.images().upload()
                .accountID("c0971a52-1f1c-4511-876a-f45c4cfd6154")
                .imageUploadRequestMultiPart(ImageUploadRequestMultiPart.builder()
                    .image(Image.builder()
                        .fileName("example.file")
                        .content(Utils.readBytesAndClose(new FileInputStream("example.file")))
                        .build())
                    .build())
                .call();

    }
}
```

**.NET**

```csharp
var res = await sdk.Images.UploadAsync(
    accountID: "c0971a52-1f1c-4511-876a-f45c4cfd6154",
    body: new ImageUploadRequestMultiPart() {
        Image = new Image() {
            FileName = "example.file",
            Content = System.IO.File.ReadAllBytes("example.file"),
        },
    }
);
```

**PHP**

```php
$imageUploadRequestMultiPart = new Components\ImageUploadRequestMultiPart(
    image: new Components\Image(
        fileName: 'example.file',
        content: file_get_contents('example.file');,
    ),
);

$response = $sdk->images->upload(
    accountID: 'c0971a52-1f1c-4511-876a-f45c4cfd6154',
    imageUploadRequestMultiPart: $imageUploadRequestMultiPart

);
```

The response will include an `imageID` which can be used to get metadata, replace, or delete an image.

The `link` is the public URL to access the image. You can add a `size={width}x{height}` parameter to the public URL to resize the image. Additionally, the `publicID` is a unique identifier which is used in the URL and can also be used in public endpoints.

```json
{
  "imageID": "bbdcb050-2e05-43cb-812a-e1296cd0c01a",
  "publicID": "string",
  "altText": "string",
  "link": "https://api.moov.io/images/qJRAaAwwF5hmfeAFdHjIb",
  "createdOn": "2019-08-24T14:15:22Z",
  "updatedOn": "2019-08-24T14:15:22Z"
}
```

## Manage images

Once an image has been uploaded, you can retrieve a list of all image metadata, or get a singular image's metadata. You can also update an image's metadata, or replace an existing image, including its metadata.

Deleting an image permanently removes it from Moov.

### Retrieve metadata

Retrieve a list of all image metadata, or get metadata for a specific image.

**List all image metadata**

```zsh
curl -X GET "https://api.moov.io/accounts/{accountID}/images" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00"
```

**Get image metadata**

```zsh
curl -X GET "https://api.moov.io/accounts/{accountID}/images/{imageID}" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00"
```

### Update an image

You can replace an image and, optionally, its metadata, or you can just update its metadata.

**cURL - Replace image**

```zsh
curl -X PUT "https://api.moov.io/accounts/{accountID}/images/{imageID}" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00" \
  --data '{
    "image": "00010101011111001111000101010",
    "metadata": {
      "altText": "Red soy milk carton by Fancy Brand"
    }
  }'
```

**cURL - Update metadata**

```zsh
curl -X PUT "https://api.moov.io/accounts/{accountID}/images/{imageID}/metadata" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00" \
  --data '{
    "altText": "New! Updated recipe, blue oat milk by Fancy Brand"
  }'
```

### Delete an image

Deleting an image permanently removes it from your collection stored with Moov.

**cURL**

```zsh
curl -X DELETE "https://api.moov.io/accounts/{accountID}/images/{imageID}" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00"
```

**TypeScript**

```typescript
const result = await moov.images.delete({
  accountID: "866c32ce-2536-4b21-8e12-f8c474fb2a9b",
  imageID: "ca048253-31d2-4bfb-9077-1f07a2a09f26",
});
```

**Python**

```python
res = moov.images.delete(account_id="866c32ce-2536-4b21-8e12-f8c474fb2a9b", image_id="ca048253-31d2-4bfb-9077-1f07a2a09f26")
```

**Ruby**

```ruby
res = s.images.delete(account_id: '866c32ce-2536-4b21-8e12-f8c474fb2a9b', image_id: 'ca048253-31d2-4bfb-9077-1f07a2a09f26')
```

**Java**

```java
        DeleteImageResponse res = sdk.images().delete()
                .accountID("866c32ce-2536-4b21-8e12-f8c474fb2a9b")
                .imageID("ca048253-31d2-4bfb-9077-1f07a2a09f26")
                .call();

        // handle response
    }
}
```

**.NET**

```csharp
var res = await sdk.Images.DeleteAsync(
    accountID: "866c32ce-2536-4b21-8e12-f8c474fb2a9b",
    imageID: "ca048253-31d2-4bfb-9077-1f07a2a09f26"
);
```

**PHP**

```php
$response = $sdk->images->delete(
    accountID: '866c32ce-2536-4b21-8e12-f8c474fb2a9b',
    imageID: 'ca048253-31d2-4bfb-9077-1f07a2a09f26'

);
```

## In the Dashboard

Navigate to **Image library** in the Dashboard. Images uploaded to the library must be in PNG, JPG, or WebP format, and cannot exceed 16MB. Every image is given a unique image ID, which can be linked to products in your [product catalog](/guides/account-tools/product-catalog/index.md).

![Image library in the Dashboard](images/image-library-view.png)

After you upload an image, select it to view the public URL and the image ID. You can add alt text, or append the public URL with a width and height parameter (`?size=[width]x[height]`) to scale and crop the image to a specific size.

![Edit image in the Dashboard](images/edit-image-library.png)

Delete an image by hovering over it and selecting the trash icon, or by clicking the **Delete** button inside the editing modal.

