> ## Documentation Index
> Fetch the complete documentation index at: https://developer.dashsocial.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Build shoppable galleries with the API

> Build fully custom shoppable galleries using the Dash Social API for complete design control.

## Overview

Use Dash Social's API to build fully custom Shoppable Galleries that match your brand's layout and infrastructure. The API gives you complete design control, avoids third-party JavaScript, and supports server-side rendering with localized product data.

For a fast, prebuilt option with minimal setup, see the Shoppable Gallery Widget →

<CardGroup cols={1}>
  <Card title="Shoppable Gallery Widget Setup" href="https://developer.dashsocial.com/guides/social-commerce/shoppable-and-product-page-galleries/shoppable-gallery/shoppable-gallery-widget-setup">
    Embed Shoppable Galleries on your site with a quick JavaScript widget and minimal setup.
  </Card>
</CardGroup>

## Before you start

You'll need:

* **Brand ID**: Visible in your developer settings or next to your brand name in the platform
* **Gallery ID**: Retrieved from the URL in Dash Social (see Step 2)
* Your product feed is set up and synced in the Dash Library. [Set up your product feed](https://developer.dashsocial.com/guides/social-commerce/product-feed/product-feed-setup-guide).

### Access requirements

* No API key or authentication required
* Rate limited per IP address

## Implementation

### Step 1: Create a gallery in Dash Social

If you haven't already created a gallery:

1. Go to the **Library** and click **Add Gallery**
2. Add UGC or owned media by clicking **Add Media**
3. Tag each media item with products by selecting **Link**

<Info>Already have a gallery? Skip this step and jump to Step 2.</Info>

### Step 2: Retrieve the gallery ID

Once the gallery is created, get your `gallery_id` from the URL.

**Example URL:**

```text theme={null}
https://app.dashsocial.com/{brand_name}/library/galleries?sort=CREATED&sort_order=DESC&tags_filter_type=OR&graph_start_date=2025-05-29&graph_end_date=2025-06-04&graph_scale=DAILY&graph_reporting_period_mode=LAST_7_DAYS&d=boardDetail%7CboardId%3A5448990%26galleryType%3ALIBRARY%26isCompetitors%3Afalse
```

* `%3A` is a URL-encoded colon `(:)`
* The **Gallery ID** is the number directly after `boardId:`
  In this case, it's `5448990`

### Step 3: Retrieve gallery content

Use the following endpoint to get the media associated with a gallery:

```http theme={null}
GET https://library-backend.dashsocial.com/public/brands/{brand_id}/galleries/{gallery_id}/media?sort=ORDER
```

<Info>This endpoint requires no API key. You can call it directly from your frontend without exposing credentials. It works from the backend too.</Info>

* `sort`: Sorts media by field. Prefix with `-` for descending order. Common values:
  * `ORDER`: Returns media in the same order as the Dash UI
  * `PUBLISHED_AT`: Sorts by publish date, newest first
  * `PERFORMANCE`: Sorts by engagement performance

For full parameter and response details, see the [API reference](/api-reference/library/publicgallery/get-publicbrands-galleries-media).

Sample response:

```json theme={null}
{
    "data": [
        {
            "brand_media_type": "LINKEDIN_OWNED",
            "id": 72896870,
            "media": {
                "duration": null,
                "id": 652015248,
                "image_sizes": {
                    "medium_square": {
                        "height": 640,
                        "url": "https://images.dashsocial.com/...",
                        "width": 640
                    },
                    "original": {
                        "height": 366,
                        "url": "https://images.dashsocial.com/...",
                        "width": 550
                    }
                },
                "source": "LINKEDIN",
                "type": "IMAGE",
                "urls": {
                    "full": "https://images.dashsocial.com/...",
                    "thumbs": "https://images.dashsocial.com/..."
                },
                "video_sizes": {}
            },
            "order": 6.0,
            "products": []
        },
        {
            "brand_media_type": "LINKEDIN_OWNED",
            "id": 72896866,
            "media": {
                "duration": 11.266667,
                "id": 656722487,
                "image_sizes": {
                    "medium_square": {
                        "height": 640,
                        "url": "https://images.dashsocial.com/...",
                        "width": 640
                    },
                    "original": {
                        "height": 1280,
                        "url": "https://cdn.dashsocial.com/...",
                        "width": 720
                    }
                },
                "source": "LINKEDIN",
                "type": "VIDEO",
                "urls": {
                    "full": "https://cdn.dashsocial.com/...",
                    "thumbs": "https://images.dashsocial.com/..."
                },
                "video_sizes": {
                    "original": {
                        "height": 1280,
                        "size": 2122842,
                        "url": "https://cdn.dashsocial.com/...",
                        "width": 720
                    }
                }
            },
            "order": 10.0,
            "products": [
                {
                    "id": 9633502,
                    "image_url": null,
                    "source_id": null,
                    "title": "Product Title",
                    "url": "https://example.com/product",
                    "x": 0.433333,
                    "y": 0.4625
                }
            ]
        }
    ],
    "paging": {
        "count": 12,
        "next": null,
        "previous": null
    }
}
```

<Info>**Pro tip:** Cache gallery data in your backend to reduce load times and API usage. If speed is a high priority feature for you, we recommend caching the results to avoid calling the API every time users load your website.</Info>

### Filter archived products

Each product in the response includes an `archived` field. Use it to decide whether to hide or display archived products differently in your gallery.

```json theme={null}
{
  "archived": false,
  "id": 9633502,
  "title": "Product Title"
}
```

* `archived: true`: the product is archived
* `archived: false`: the product is active

### Step 4: Render the gallery on your website

Now that you have the media data and linked product data, render the gallery in any format that fits your site design: carousel, grid, list, or any other layout.

***

## Optional: Display UGC creator info and caption

By default, the gallery API returns a summarized response without post-level metadata. If you want to show creator handles, captions, or engagement details in your gallery UI, you need to use the private authenticated endpoint with `summary=0`.

<Info>This requires an API key. The public endpoint does not return `source_data`.</Info>

<CardGroup cols={1}>
  <Card title="API Quickstart" href="/guides/get-started/quickstart">
    Generate an API key and make your first authenticated request.
  </Card>
</CardGroup>

```http theme={null}
GET https://library-backend.dashsocial.com/brands/{brand_id}/galleries/{gallery_id}/media?summary=0
```

When `summary=0` is set, each media item includes a `source_data` object with post-level and user-level metadata. For Instagram UGC, use `media.source_data.instagram_user.handle` to display the creator's handle.

Sample response:

```json theme={null}
{
    "data": [
        {
            "brand_media_type": "INSTAGRAM_UGC",
            "id": 54378431,
            "media": {
                "duration": null,
                "id": 460069447,
                "image_sizes": {
                    "medium_square": {
                        "height": 640,
                        "url": "https://images.dashsocial.com/...",
                        "width": 640
                    },
                    "original": {
                        "height": 1800,
                        "url": "https://cdn.dashsocial.com/...",
                        "width": 1440
                    }
                },
                "source": "INSTAGRAM",
                "source_data": {
                    "caption": "Loving the new summer collection! #summer #ootd",
                    "hashtags": ["summer", "ootd"],
                    "id": "17927322830848120",
                    "image_url": "https://cdn.dashsocial.com/...",
                    "instagram_media_type": "FEED",
                    "instagram_user": {
                        "followers": 12400,
                        "handle": "example_creator",
                        "instagram_id": 64685177677,
                        "is_business": 0
                    },
                    "like_count": 184,
                    "timestamp": "2025-04-08T13:19:48+0000",
                    "type": "image",
                    "url": "https://www.instagram.com/p/..."
                },
                "type": "IMAGE",
                "urls": {
                    "full": "https://cdn.dashsocial.com/...",
                    "thumbs": "https://images.dashsocial.com/..."
                },
                "video_sizes": {}
            },
            "order": 4.0,
            "products": [
                {
                    "id": 9633502,
                    "image_url": "https://cdn.dashsocial.com/products/original_images/...",
                    "source_id": "SKU-001",
                    "title": "Summer Dress",
                    "url": "https://example.com/products/summer-dress",
                    "x": 0.453125,
                    "y": 0.4625
                }
            ]
        }
    ],
    "paging": {
        "count": 4,
        "next": null,
        "previous": null
    }
}
```

***

## Optional: Localize your gallery content

If you serve international audiences, you can request localized product data for a specific region by adding the `include_product_overrides` parameter to your API call.

This lets you:

* Show translated product titles
* Display region-specific pricing and currency
* Link to localized product pages

### Prerequisites

Before localizing your Shoppable Gallery, make sure you:

* **Set up a localized product feed** in Dash Social. Follow the [Localized Product Feed Setup Guide](https://developer.dashsocial.com/guides/social-commerce/product-feed/localized-product-feed-setup-guide).
* **Note your override identifier** (e.g., `DK`, `FR`). The value passed to `include_product_overrides` must match the override name configured in your Dash Social library.

### Implementation

Add `include_product_overrides` to your request with the locale identifier:

```http theme={null}
GET https://library-backend.dashsocial.com/public/brands/{brand_id}/galleries/{gallery_id}/media?include_product_overrides={locale}
```

For example, to request Danish product data:

```http theme={null}
GET https://library-backend.dashsocial.com/public/brands/144/galleries/6925134/media?include_product_overrides=DK
```

If a product has a matching override, it is returned in the `product_overrides` array. If no match exists, the media item is still returned but `product_overrides` will be `null`.

Render the localized values from `product_overrides`:

* `title`
* `price` and `currency_code`
* `url`

Fall back to the default product fields if `product_overrides` is `null`.

Sample response:

```json theme={null}
{
    "data": [
        {
            "brand_media_type": "PINTEREST_OWNED",
            "id": 73746344,
            "media": {
                "duration": null,
                "id": 323843713,
                "image_sizes": {
                    "medium_square": {
                        "height": 640,
                        "url": "https://images.dashhudson.com/...",
                        "width": 640
                    },
                    "original": {
                        "height": 900,
                        "url": "https://images.dashhudson.com/...",
                        "width": 1200
                    }
                },
                "source": "PINTEREST",
                "type": "IMAGE",
                "urls": {
                    "full": "https://images.dashhudson.com/...",
                    "thumbs": "https://images.dashhudson.com/..."
                },
                "video_sizes": {}
            },
            "order": 0.0,
            "products": [
                {
                    "id": 9729122,
                    "image_url": "https://cdn.dashhudson.com/products/original_images/...",
                    "product_overrides": [
                        {
                            "currency_code": "DKK",
                            "id": 1118,
                            "override": "DK",
                            "price": "DKK 299.00",
                            "source_id": "SKU-001",
                            "title": "Høj hæl sandal",
                            "url": "https://example.com/dk/products/sandal-001"
                        }
                    ],
                    "source_id": "SKU-001",
                    "title": "High Heel Sandal",
                    "url": "https://example.com/products/sandal-001",
                    "x": 0.728261,
                    "y": 0.507246
                },
                {
                    "id": 9729123,
                    "image_url": null,
                    "product_overrides": [
                        {
                            "currency_code": "DKK",
                            "id": 1119,
                            "override": "DK",
                            "price": "DKK 659.00",
                            "source_id": "SKU-002",
                            "title": "Ankelstøvle med spænde",
                            "url": "https://example.com/dk/products/ankle-boot-002"
                        }
                    ],
                    "source_id": "SKU-002",
                    "title": "Ankle Boot",
                    "url": "https://example.com/products/ankle-boot-002",
                    "x": 0.396739,
                    "y": 0.481884
                }
            ],
            "updated_at": "2026-05-25T17:07:00+00:00"
        }
    ],
    "paging": {
        "count": 13,
        "next": null,
        "previous": null
    }
}
```

## Server-side caching

Shoppable Gallery content typically updates less frequently than product pages, making it ideal for caching on your server to reduce API calls and speed up page loads.

### Why cache API responses?

* **Faster gallery rendering:** Serve content instantly without waiting for a live API call.
* **Lower API usage:** Minimize repeated requests and stay within rate limits.
* **Stable experience:** Cached data ensures the gallery loads smoothly even during heavy traffic.

### Recommended cache duration

* Since Shoppable Galleries update less often, you can safely use a longer TTL (e.g., **24–48 hours**).
* If your gallery is updated regularly with new UGC or campaigns, use a shorter TTL (e.g., **6–12 hours**).

<Info>**Tip:** Match the cache duration to how often you update your gallery content. Longer TTLs work best for static or seasonal galleries, while active campaigns benefit from shorter intervals.</Info>
