Bowmark AIdocs

Therabody

Therabody (Theragun) product catalogue — every device, its variants, its prices and what is in stock — read off the live Shopify storefront.

Domain: therabody.com

Also known as: therabody, Therabody, Theragun

Call it directly

bowmark.providers.therabody.listTheragunProducts(opts?: { limit?: number }): Promise<TherabodyProduct[]>
bowmark.providers.therabody.getTheragunProduct(handle: string): Promise<TherabodyProduct>
bowmark.providers.therabody.recommendTheragun(criteria: { audience?: string; features?: string[]; inStockOnly?: boolean }): Promise<TherabodyRecommendation>

Functions

FunctionWhat it does
listTheragunProductsReads the live Therabody catalogue as Therabody publishes it — every product, its handle, title, vendor, description, tags, images and the per-variant price the storefront is quoting right…
getTheragunProductReads one product by its handle — every variant, its exact price, the image the storefront is showing and whether that specific variant is purchasable right now.
recommendTheragunFilters the live catalogue by what a shopper actually needs — device family, audience, and the features named (percussive, recovery, massage, vibration). Returns the matching products with…

Types

interface TherabodyVariant {
  /** Shopify's numeric variant id as a string. The future addToCart entry. */
  id: string;
  /** The variant's own label, e.g. "Default Title". */
  title: string;
  /** Decimal string exactly as the store publishes it, e.g. "54998" (cents). */
  price: string;
  /** Same scale as price. Null when the product is not on sale. */
  compareAtPrice: string | null;
  /** The store's own SKU. Null on a product without one. */
  sku: string | null;
  /** Whether the variant is purchasable right now. */
  available: boolean;
  options: string[];
}
interface TherabodyProduct {
  /** The handle is the only stable identifier across the catalogue. */
  handle: string;
  title: string;
  vendor: string;
  productType: string;
  url: string;
  descriptionHtml: string | null;
  optionNames: string[];
  variants: TherabodyVariant[];
  /**
   * The store's own price scale per endpoint — see TherabodyVariant.price for
   * why the two strings may differ. Range keeps the same scale as the input.
   */
  priceRange: { min: string; max: string } | null;
  /** True if ANY variant is purchasable. The "is it in stock?" answer. */
  inStock: boolean;
  tags: string[];
  /** Therabody's own images, in the order the storefront publishes them. */
  images: string[];
}
interface TherabodyRecommendation {
  /** The matching products, in-stock first, then by handle. */
  products: TherabodyProduct[];
  /** What the filter DROPPED, in the same register the rest of the library uses. */
  warnings: string[];
}

Examples

// what are the cheapest Theragun devices in stock right now?
const all = await bowmark.providers.therabody.listTheragunProducts({ limit: 50 });
const inStock = all.filter(p => p.inStock).sort((a, b) => Number(a.priceRange?.min ?? 0) - Number(b.priceRange?.min ?? 0));
log(inStock.slice(0, 5).map(p => `${p.title} from $${p.priceRange?.min}`).join(", "));
// what are the variants of this Theragun, and which is left?
const p = await bowmark.providers.therabody.getTheragunProduct("theragun-prime-gen-6-massage-gun-navy");
const left = p.variants.filter(v => v.available);
log(left.length ? left.map(v => v.title).join(", ") : `${p.title} is sold out`);