Medusa Athos Integration Plugin.
Medusa v2 plugin that generates a streaming NDJSON product feed for Athos Commerce integration.
yarn add @weareseeed/medusa-athos-plugin
// medusa-config.tsimport { defineConfig } from "@medusajs/framework/config"export default defineConfig({plugins: [{resolve: "@weareseeed/medusa-athos-plugin",options: {},},],})
npx medusa db:migrate
Set the plugin configuration through the authenticated admin endpoint:
curl -X POST http://localhost:9000/admin/athos/config \-H "Authorization: Bearer <admin_token>" \-H "Content-Type: application/json" \-d '{"storefront_url": "https://mystore.com","feed_token": "a-secret-token","region_id": "reg_01...","sales_channel_ids": ["sc_01..."],"swatch_option_titles": ["color", "colour"]}'
| Field | Type | Required | Description |
|---|---|---|---|
| Yes | Base URL prepended to for each product URL | ||
| Yes | Secret token required to access the feed endpoint | ||
| No | When set, prices are filtered to the region's currency | ||
| No | When set, only products in these sales channels are included | ||
| No | Option titles treated as swatches (default: ) |
Returns an stream. Each product produces:
| Field | Description |
|---|---|
| Variant ID | |
| Variant SKU | |
| Variant title | |
| Lowest price for the variant (filtered by region if configured) | |
| Product thumbnail | |
| Product description | |
| Array of category path strings (e.g. ) | |
| Array of category IDs | |
| Comma-separated product tags | |
| Parent product ID | |
| Parent product title | |
| Parent product thumbnail | |
| 1-based position within the product | |
| if the variant is available | |
| % of variants in stock across the product | |
| All product options with positions and values | |
| This variant's chosen option values | |
| Values of configured swatch options (product-level) |
Same as variant line minus all private fields, with set to the product ID and set to the lowest price across all variants.
{"Product ID":"variant_01...","SKU":"1","Name":"blue, m","Product URL":"https://mystore.com/products/example","Price":10,"Thumbnail URL":"https://...","Description":"...","Category":["Tops"],"Category ID":["pcat_01..."],"__parent_id":"prod_01...","__parent_title":"Example Product","__parent_image":"https://...","__variant_position":1,"__in_stock":true,"__in_stock_pct":100,"__standard_options":{"color":{"position":0,"values":["red","blue"]},"size":{"position":1,"values":["s","m"]}},"__selected_options":{"color":{"value":"blue"},"size":{"value":"m"}},"__swatch_options":{"red":{"value":"red"},"blue":{"value":"blue"}}}{"Product ID":"prod_01...","Name":"Example Product","Product URL":"https://mystore.com/products/example","Price":10,"Thumbnail URL":"https://...","Description":"...","Category":["Tops"],"Category ID":["pcat_01..."]}
Pass options when registering the plugin in to extend the feed.
import { defineConfig } from "@medusajs/framework/config"import type { FeedLineContext } from "@weareseeed/medusa-athos-plugin/types"export default defineConfig({plugins: [{resolve: "@weareseeed/medusa-athos-plugin",options: {feed: {extraProductFields: ["metadata", "variants.metadata"],transformLine: (line, ctx: FeedLineContext) => {line["Brand"] = (ctx.product as any).metadata?.brand ?? undefinedif (ctx.type === "variant") {line["Custom Variant Field"] = (ctx.variant as any).metadata?.custom ?? undefined}if (ctx.type === "product") {line["Custom Product Field"] = (ctx.product as any).metadata?.custom ?? undefined}return line},},},},],})
— Additional Medusa product fields to fetch and make available inside . Uses the same dot-notation field paths as Medusa's .
extraProductFields: ["metadata","variants.metadata","images.url","collection.title",]
(line: Record<string, unknown>, ctx: FeedLineContext) =>Record<string, unknown> | Promise<Record<string, unknown>>
Called for every line written to the feed. Use it to add, remove, or transform fields. The argument provides typed access to the raw product and variant data:
type FeedLineContext =| { type: "variant"; product: Record<string, unknown>; variant: Record<string, unknown>; variantIndex: number }| { type: "product"; product: Record<string, unknown> }
Fields that resolve to are automatically stripped from the output.
Both endpoints require an authenticated admin JWT.
| Method | Path | Description |
|---|---|---|
| Retrieve the current configuration | ||
| Create or update the configuration |
MIT — Seeed