> ## 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.

# updateOffersWorkflow

> Update offer rows and rewrite their price ladders with replace semantics.

Applies partial updates to offer rows (`sku`, `shipping_profile_id`, `metadata`). When an entry sets `prices`, the offer's price ladder is rewritten with replace semantics: rows with `id` are updated in place, rows without `id` are added, and existing offer-owned prices omitted from the array are removed — all on the variant's shared `PriceSet`, scoped by the `offer_id` price rule. Price ownership is asserted so an offer can't touch another offer's rows. Emits `offer.updated`. Triggered by `POST /vendor/offers/:id` and the offer batch routes.

## Usage

```ts theme={null}
import { updateOffersWorkflow } from "@mercurjs/core/workflows"

const { result } = await updateOffersWorkflow(container).run({
  input: {
    offers: [
      {
        id: "offer_123",
        prices: [{ amount: 1799, currency_code: "usd" }],
      },
    ],
  },
})
```

## Input

<ParamField body="offers" type="object[]" required>
  Offer updates, keyed by ID.

  <Expandable title="properties">
    <ParamField body="id" type="string" required>The offer to update; fails if not found.</ParamField>
    <ParamField body="sku" type="string">New SKU.</ParamField>
    <ParamField body="shipping_profile_id" type="string">New shipping profile.</ParamField>
    <ParamField body="metadata" type="object | null">Custom key-value data.</ParamField>
    <ParamField body="prices" type="object[]">Full replacement price ladder; each row accepts `id` (update in place when set), `amount`, `currency_code`, `min_quantity`, `max_quantity`, and `rules`. Omit the field to leave prices untouched.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="additional_data" type="object">Custom data passed through to the workflow hooks.</ParamField>

## Result

<ResponseField name="result" type="OfferDTO[]">The updated offers.</ResponseField>

## Hooks

* `validate` — runs first with `{ input }`.
* `offersUpdated` — runs after the update with `{ offers, additional_data }`.

```ts theme={null}
updateOffersWorkflow.hooks.offersUpdated(async ({ offers, additional_data }) => {
  // react to updated offers
})
```
