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

# Offer module

> Data models, links, and service methods for the Offer module.

The Offer module owns a seller's **listing** — the binding of a shared product variant to that seller's SKU, shipping profile, price, and inventory. Products in Mercur are master catalog records; the offer is what makes a variant purchasable *from a specific seller*.

## Data models

### `Offer`

Table `offer`, ID prefix `offer`. Unique on (`seller_id`, `sku`).

| Field                 | Type   | Notes                                              |
| --------------------- | ------ | -------------------------------------------------- |
| `seller_id`           | text   | The listing seller                                 |
| `product_id`          | text   | The master product                                 |
| `variant_id`          | text   | The listed variant                                 |
| `shipping_profile_id` | text   | The seller's shipping profile for this offer       |
| `sku`                 | text   | Searchable; unique per seller                      |
| `ean` / `upc`         | text   | Nullable, searchable                               |
| `created_by`          | text   | Actor that created the offer                       |
| `variant_count`       | number | Computed; only populated in `group_by_seller` mode |
| `metadata`            | json   | Nullable                                           |

Indexes exist on `variant_id`, `product_id`, `seller_id`, `shipping_profile_id`, `ean`, and `upc`.

## Links

Prices and inventory attach to the offer through links, not columns:

| Linked entity                                                                 | Cardinality                                                                | Purpose                                                             |
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `Pricing.price`                                                               | one offer — many prices                                                    | The offer's own price set                                           |
| `Inventory.inventoryItem`                                                     | many-to-many (`offer_inventory_item`, with `required_quantity`, default 1) | The stock backing the offer                                         |
| `Cart.lineItem` / `Order.orderLineItem`                                       | one offer — many items                                                     | Traces cart and order lines back to the offer they were bought from |
| `Product.product` / `productVariant`, `Seller`, `Fulfillment.shippingProfile` | read-only                                                                  | Resolved from the `*_id` columns                                    |

<Warning>
  Offer inventory links to the **offer**, not the variant. For offer-backed
  order lines, `variant.inventory_items` is empty — always read stock through
  the offer's inventory link.
</Warning>

## Service

`OfferModuleService` extends `MedusaService` with auto-generated CRUD, plus a grouped listing mode:

| Method                                                    | Behavior                                                                                                                                                               |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listOffers(filters, config)` / `listAndCountOffers(...)` | When `filters.group_by_seller` is set, collapses results to one row per (`product_id`, `seller_id`) and computes `variant_count` per group; otherwise standard listing |

## Related endpoints

* `GET /admin/offers`, `POST /admin/offers/batch` — operator visibility and bulk creation
* `GET/POST /vendor/offers`, `POST /vendor/offers/batch`, `POST /vendor/offers/:id/inventory-items/batch` — seller listing management
* `GET /store/offers`, `GET /store/offers/:id` — storefront discovery with per-offer calculated prices

## Next steps

<CardGroup cols={2}>
  <Card title="Seller module" href="/rc/references/modules/seller" />

  <Card title="Search module" href="/rc/references/modules/search" />
</CardGroup>
