Discover over 50,000 artworks from the National Gallery of Art using natural language.
Before you begin, you’ll need:
- Node.js 22
- Mixedbread account — sign up at https://platform.mixedbread.com
- Mixedbread API Key — create at https://platform.mixedbread.com/platform?next=api-keys
- A Mixedbread Store (name or ID) holding your images
- Optional: Resend credentials if you want the feedback form to send emails
Images are from the National Gallery of Art’s Free Images and Open Access Program:
https://www.nga.gov/artworks/free-images-and-open-access
Huge thanks to the NGA for enabling research and demos like this with their public dataset.
- Install dependencies
bun install- Configure environment variables
cp .env.example .envEdit .env and set your Mixedbread key:
MXBAI_API_KEY=your_api_key_hereOptional (feedback emails):
RESEND_API_KEY=...
RESEND_FROM_EMAIL=...
RESEND_TO_EMAIL=...- Point the API route at your store
Update the store_identifiers value in app/api/search/route.ts to your store’s name or ID:
// app/api/search/route.ts
const res = await mxbai.stores.search({
query,
store_identifiers: ["YOUR_STORE_NAME"],
top_k: 16,
search_options: { score_threshold: 0.55 },
});- Start the dev server
bun devThis minimal example creates a store and uploads all .png files from a directory, waiting for processing to complete.
//scripts/upload-pngs.ts
import { Mixedbread } from "@mixedbread/sdk";
import { readdir } from "node:fs/promises";
import { createReadStream } from "node:fs";
import path from "node:path";
async function main() {
const apiKey = process.env.MXBAI_API_KEY;
if (!apiKey) throw new Error("Missing MXBAI_API_KEY");
const mxbai = new Mixedbread({ apiKey });
const storeName = "your-store";
const imagesDir = path.resolve("./data/images");
const files = (await readdir(imagesDir)).filter((f) => /\.png$/i.test(f));
for (const filename of files) {
const filePath = path.join(imagesDir, filename);
const uploaded = await mxbai.stores.files.uploadAndPoll({
storeIdentifier: storeName,
file: createReadStream(filePath),
body: { filename, metadata: { source: "NGA", path: filePath } },
});
console.log(`Processed: ${uploaded.filename} -> ${uploaded.status}`);
}
}
main().catch((err) => {
console.error(err);
process.exit(1);
});Run with Bun:
bun scripts/upload-pngs.ts- Natural language search over artworks
- Multimodal retrieval via Omni (text, image, audio, video)
- Built on a public, open-access image dataset
- Credentials: Ensure
MXBAI_API_KEYis set in.envand your shell. - Store name: Update
app/api/search/route.tswith your actual store name or ID. - Content indexed: Upload PNGs to your store and wait for processing (
uploadAndPoll). - Search thresholds: Adjust
score_thresholdortop_kfor your dataset.
- Artworks courtesy of the National Gallery of Art (NGA)
- Demo built by Mixedbread