Coordinated yoga outfit shopping
Search for a coordinated yoga outfit across lululemon, Beyond Yoga and Alo Yoga in one call — one normalized row shape per product, with each retailer's…
Search for a coordinated yoga outfit across lululemon, Beyond Yoga and Alo Yoga in one call — one normalized row shape per product, with each retailer's own published garment type, colour family and fabric names carried through so a caller can spot a plausible top-and-bottom pair. Never a claim that any retailer sold two items as a set.
Also known as: shop for coordinated yoga outfits across retailers, yoga outfit, matching yoga set, coordinated activewear, yoga outfit shopping, coordinate a yoga outfit
Call it
bowmark.yoga_outfit_shopping.search(query: string, options?: { limit?: number; timeoutMs?: number }): Promise<YogaOutfitSearchResult>Functions
| Function | What it does |
|---|---|
search | Fans out one free-text query to lululemon, Beyond Yoga and Alo Yoga in parallel and returns every match as one normalized row per product. |
Types
interface YogaOutfitItem {
source: string // "lululemon" | "beyondyoga" | "aloyoga"
title: string
url: string
image: string | null // null when the leg carries none (lululemon's search rows never do)
priceLow: number | null
priceHigh: number | null
currency: string | null // null when the leg doesn't publish one (lululemon's search door never does)
inStock: boolean
garmentType: string | null // the retailer's OWN published label, transcribed — null if the leg
// doesn't publish one (lululemon never does; the Shopify legs' search
// door doesn't either, only getProduct's REST door does)
colorFamily: string | null // shared-colour evidence — null for lululemon
fabrics: string[] // retailer-published fabric names — [] for lululemon
}
interface YogaOutfitSearchResult {
items: YogaOutfitItem[]
warnings: string[] // always present. Names a retailer that timed out or errored;
// ALL THREE dead throws instead of returning an empty result
}
type CallOptions = {
timeoutMs?: number // per-provider budget in ms, default 30000, clamped to 1000-55000.
// A provider slower than this is DROPPED from the results and
// NAMED in warnings — never silently absent
}Examples
// Coordinating a top and a bottom across three retailers, WITHOUT pretending
// any of them sold the pair as a set.
const { items, warnings } = await bowmark.yoga_outfit_shopping.search("yoga tank and leggings", { limit: 10 });
for (const w of warnings) log(w); // e.g. a retailer that timed out
// Group by the retailer's OWN published garment label — null on lululemon,
// since its search rows never carry one.
const tops = items.filter(i => i.garmentType === "tank" || i.garmentType === "sports_bra" || i.garmentType === "crop_top");
const bottoms = items.filter(i => i.garmentType === "leggings" || i.garmentType === "shorts");
// The weak, honest signal: shared colour family, from the SAME retailer (a
// colour name is never comparable across brands' own vocabularies).
const pairs = tops.flatMap((t) =>
bottoms
.filter((b) => b.source === t.source && b.colorFamily && b.colorFamily === t.colorFamily)
.map((b) => ({ top: t.title, bottom: b.title, source: t.source, sharedColorFamily: t.colorFamily })),
);
return { candidateCount: items.length, pairs };Providers behind it
| Provider | |
|---|---|
lululemon | lululemon |
beyondyoga | Beyond Yoga |
aloyoga | Alo Yoga |