Skip to main content

Sync prices with your sales channels

Two systems can hold a price for the same product, and only one of them can be right. Master of price is the setting that decides which. Once you've chosen, SKU.io either sends your price out to the channel or reads the channel's price back in — and when it sends, a set of guardrails checks every price on the way out, so a mistake in a spreadsheet can't reprice your whole catalogue on a live marketplace.

You set this per channel, so Amazon can follow your prices while eBay keeps its own.

Before you begin

  • The channel must already be connected. See Connect a Shopify store for what connecting looks like.
  • You need permission to change that channel's settings.
  • If you want SKU.io to send prices out, you need at least one price level to send them from.

Choose which side owns the price

  1. Go to Apps & Integrations and open the channel.
  2. Open Settings, then the Pricing Sync tab.
  3. Under Pricing Settings, set Master of Price:
ChoiceWhat happens
SKU.ioYour prices are sent out to the channel.
The channel's own name (for example Amazon)The channel's prices are read back in, and the marketplace stays in charge.
NeitherNothing moves in either direction.
  1. If you chose SKU.io, pick a Pricing Tier. That supplies the number that gets sent, so this is required — without it there's no price to send.
  2. Click Save Changes.

Choose which price to send

Everything from here down is on the same tab, in the Push prices to [channel] card.

One price level rarely fits a whole catalogue. Which price to send lets you list several, in order. For each product, SKU.io works down the list and sends the first level that has a price for it — so a product with no price at one level simply falls through to the next.

That ordering is what makes a one-product experiment cheap. Put a sparse level like Special first and a catch-all like Retail behind it, and the only products that use Special are the ones you've actually given a Special price. Give one product a Special price and it's the price that goes out. Delete that price again and the product falls back to Retail on its own. Nothing else to set, and nothing to remember to undo.

  1. Under Which price to send, the first card is your first choice.
  2. Click Add a fallback to put a level behind it.
  3. Use the arrows on a card to move it earlier or later, and the × to remove it.
  4. Click Save Changes.

Each card shows how much of your catalogue that level actually prices — "3 of 4,012 products priced" — and a line beneath the row totals it up: how many products will use the first level, how many fall through, and how many have no price at any level. Those last ones are reported as Not priced and nothing is sent for them.

tip

Order matters, and a calculated level (one derived from another, like Retail minus 10%) has a price for every product it can compute. Put one anywhere except last and nothing after it is ever reached — SKU.io warns you and dims the levels that have become unreachable.

note

An archived level is hidden from the pickers but keeps supplying prices to any sequence it's already in. Archiving retires a level from future use; it doesn't strip the prices it's currently supplying. Remove it from the sequence if that's what you want.

Set the guardrails

Guardrails are checked immediately before every price is sent — on every path. That includes a tier change, an imported price, and an automatic repricing rule. There's no way to send a price that skips them.

The sequence above decides which price to send. The guardrails decide whether that price is allowed out — and, in one case, adjust it. They're checked against whichever level won, and unlike the sequence they have no order between them.

Price floor

Stops a price going out below your lower limit.

  • None — no lower limit.
  • Fixed amount — a hard minimum in your currency, for example $5.00.
  • Margin % — a minimum margin over the product's cost, so the floor moves as your costs do.
  • Pricing level — the product's own price at a level you choose. This is how you enforce a minimum advertised price: point the floor at your MAP level and every product is measured against its own MAP, not one number for the catalogue.

When a price is below it decides what happens:

  • Raise the price to the floor — the floor's price is sent instead. This is the default for a Pricing level floor, because publishing your MAP is the point of having one; refusing would leave the marketplace showing the older, non-compliant price.
  • Block the listing — nothing is sent for it. This is the default for Fixed amount and Margin %, where a price under the limit usually means something upstream is wrong and quietly publishing the limit would hide it.

Price ceiling

The same idea at the top end, with the same four sources and the same choice — Lower the price to the ceiling or Block the listing. Point it at an MSRP level to keep every product at or below its own recommended price.

note

A pricing-level bound is read per product. A product with no price at that level simply has no bound — it isn't blocked. That's different from a Margin % rule, which blocks a product with no cost, because there the rule can't be worked out at all; an absent MAP is an answer, not a gap.

Maximum change

This is the one that catches the mistake nothing else will. It measures each new price against the price you last sent to that channel, and refuses anything that moves further than the percentage you allow. A misplaced decimal in an import is caught here even when the resulting price sits comfortably between your floor and your ceiling.

When exceeded decides what happens next:

  • Block the whole run — nothing is sent, so a bad import can't get halfway in.
  • Skip that listing — everything else is sent, and the one at fault is left alone.
caution

Maximum change is measured on the price that would actually be sent, including a raise to a floor. Turning on a MAP floor over a catalogue that's drifted well below it can therefore trip this limit on the first run — which is the intended behaviour: several hundred prices moving at once is worth looking at before it happens. Review the preview, then either raise the limit for that one run or let it block and fix the underlying prices.

Choose how often it runs

How often sets the schedule: every 15 minutes, every 30 minutes, hourly, every 3 hours, every 6 hours, every 12 hours, or daily.

Between runs, only prices that have actually changed since the last successful send are included. A catalogue that's already correct costs nothing to keep in sync.

Preview before your first push

Click Preview changes. Every check runs and every outcome is recorded, and nothing is sent to the channel.

The result appears under the buttons as a count of what would have happened — pushed, skipped, blocked, failed — and the whole run is saved, so you can open it and read it line by line before you commit to anything. On a catalogue of any size this is the step that turns a leap into a decision.

When the preview looks right, click Push prices now to send for real, or just let the schedule pick it up.

Letting one large change through

Maximum change compares against the price you last successfully sent, and a refused price is never sent — so the baseline doesn't move, and the same change is refused again on every later run. It won't creep upward in steps; it stays blocked until you act.

When a large move is deliberate, use the arrow beside Push prices now and choose Push with a higher change limit. Set the limit for that run and push.

  • It applies to that run only — your saved limit is untouched.
  • It's raise-only: a value at or below the saved limit is ignored.
  • It cannot relax the price floor, the price ceiling, or the rule that refuses a zero or negative price.

The run history records the limit that was actually enforced, not the one saved in settings, so a one-off exception is still visible afterwards.

note

On a non-production connection, Push prices now is unavailable and the card says so. Preview changes still works, because a preview never transmits.

Read the pricing comparison

Every channel also has its own Pricing page — open the channel and choose Pricing. Listing by listing, it puts your price next to the price the channel last reported, so you find a disagreement before your customer does.

Four cards along the top summarise it:

CardMeaning
Out of syncThe two prices disagree. The Difference column shows by how much, in both dollars and percent.
In syncThe two match.
Channel price unknownThe channel hasn't reported a price yet, so there's nothing to compare.
Not pricedNo level in the sequence prices this product, so SKU.io has nothing to send for it.

Each card is also a filter: click Out of sync and the table narrows to just the listings that disagree. Clear it again with Clear, or by removing the chip under the search box.

You can also filter by Status, Priced from, Guardrails, Master, Push state and Last pushed, search by SKU or product, add columns from Columns, and save any combination as a view with Save current so it's one click next time.

Which level priced each product

The Priced from column names the level each row's price came from — the answer to "why is this product $19?" without opening anything. With a sequence in place that answer is genuinely per product: one row reads Special, the next Retail, because Special had a price for the first and not the second.

A dash means the price didn't come from a level at all — either nothing in the sequence prices that product, or a repricing rule set the figure directly. Filter the column by No level to find everything the sequence isn't reaching.

Two buttons at the top of the page save you a trip: Pricing Settings jumps straight to the tab above, and Push Prices Now sends from here.

Refresh what the channel says

The comparison is only as current as the last time the channel reported in. Fetch from [channel] re-reads prices from the marketplace now, so the table reflects what the channel says at this moment. It runs in the background — you can leave the page.

note

This button appears only on channels that can report their live listing state: Amazon, BigCommerce, eBay, Shopify, Walmart and WooCommerce. On the others there's no way to re-read the channel's price on demand, so no button is offered rather than one that would do nothing.

When one listing needs different rules

The guardrails you set on the Pricing Sync tab govern the whole channel. A single listing can carry an exception instead, replacing them for that listing only.

The Guardrails column on the Pricing page shows which applies to each row — Channel for the defaults, Listing where an exception is in force — so you never have to guess which rules are governing a price.

caution

An exception replaces the whole set — floor, ceiling, maximum change and the exceeded action — not just the field you came to change. A floor left as None in an exception means no floor for that listing; it does not fall back to the channel's floor.

This is deliberate: it means any refused price traces to exactly one rule, rather than to a combination of scopes each supplying different fields.

Add or edit an exception

From the Pricing page:

  • Click the Listing chip in the Guardrails column to open the exception governing that row.
  • Right-click any row and choose Set guardrail exception.
  • Tick several rows and use Set guardrail exception to apply one set of values to all of them, or Clear exceptions to return them to the channel's guardrails.

The same dialog also sets that listing's master of price and pricing tier, so you can hand one listing to the marketplace — or price it from a different tier — without leaving the page. Those two go together: choosing to override means setting both.

Two combinations are refused when you save, because they'd block every push for that listing: a floor above the ceiling, and a floor or ceiling whose type isn't None but has no value.

Review every exception

The Exceptions tab beside Comparison lists all of them for the channel — what each applies to, the values it sets, and who set it and when. When a price is behaving oddly, this is the shortest route to the rule responsible. Search by exception ID, and edit or remove from the same table.

Read a run

Click View history on the Pricing Sync tab. Each run shows when it started, what triggered it (scheduled or manual), whether it was a live push or a preview, and how many listings were pushed, skipped, blocked, or failed.

Click Details on any run to see every listing it touched, one row each, with its old price, its new price, and what happened to it. Filter that list with All, Pushed, Blocked, Failed and Skipped.

The Detail column is the useful part:

  • A blocked row names the guardrail that refused it and shows the numbers — "Below the $5.00 price floor", or "Changes by 50%, over the 25% limit" — so you can judge whether the fault was the price or the limit.
  • A pushed row is usually blank, but says so when a bound moved the price — "Raised to the $15.00 MAP floor". The row still counts as pushed, because it was; the note explains why the figure differs from the one in your catalogue.
  • A failed row carries the channel's own reply, in the channel's words.
  • A skipped row usually just says "Price unchanged" — the normal, healthy majority on a settled catalogue.
note

A scheduled run only keeps a row for each listing whose price changed or was refused. If a run's detail view is empty, it did nothing that needed recording — the unchanged listings are counted on the run itself rather than listed.

Nothing is being sent — what to check

Work down this list in order:

  1. Master of Price isn't SKU.io. If the channel owns price, SKU.io reads instead of sends. Nothing going out is the correct behaviour.
  2. No price level is set. With SKU.io as master and nothing under Which price to send, there's no price to send.
  3. No level in the sequence prices these products. A sequence made only of sparse levels leaves everything else unpriced. The Not priced card on the Pricing page counts them, and the totals under the sequence editor say how many fall through versus how many have no price at all — add a catch-all level last and the number drops to zero.
  4. The schedule is paused, or price sync is off for that channel. The card tells you which of these applies.
  5. Everything really is in sync. Only changed prices are sent, so a run that reports all skipped is a run with nothing to do.
  6. The connection isn't a production one. Previews work; live pushes don't.

If prices are being refused rather than not sent, the run history names the guardrail and the numbers — start there. If those numbers don't match the settings on the Pricing Sync tab, that listing has an exception: check the Guardrails column on the Pricing page, or the Exceptions tab.

Which channels support this

Amazon, BigCommerce, eBay, Faire, Magento 1, Magento 2, Shopify, Square, Temu, TikTok Shop, Walmart and WooCommerce each have their own Pricing Sync tab and Pricing page. The settings and the pages work the same way on every one of them.

Next steps

Video transcript

Two systems, one number. Something has to decide which of them is in charge, and that setting is called master of price. You choose it per channel, on the Pricing Sync tab of the channel's own settings. Make SKU.io the master, and your prices go out. Hand it to the marketplace instead, and what it charges becomes the source of truth. Neither, and nothing moves at all. One more thing is needed on the way out: a pricing tier, which supplies the actual number. Below that sits Which price to send. It lists your levels in order. For each product, the first one holding a price wins. Anything it does not price falls through to the next level. So a sparse level in front of a catch-all changes only the products you have actually given a special price. Around it sit the guardrails. Every value is checked the moment before it leaves SKU.io — no matter what produced it, whether a price change, a spreadsheet import, or an automatic repricing rule. A floor stops a price going out too low. A ceiling does the same at the top end. A floor can also read a pricing level, so each product is measured against its own minimum advertised price — and raised to it rather than refused. Maximum change catches a different kind of mistake. It measures each new value against the one you last sent, and refuses anything that jumps further than you allow. That is what stops a bad import from repricing an entire catalogue. You decide: block the whole run, or skip only the listing at fault. How often decides the schedule. Between runs, only prices that have actually changed since the last successful send are included, so a catalogue that is already correct costs nothing. The first push has to be previewed. Every check runs against every listing, and nothing at all is sent. It takes a moment, because this is the real thing running with the transmission switched off. When it lands, the results open right here — the whole price set the tier would produce, listing by listing, with anything that would have been refused already marked. On a catalogue of any size, that is the difference between a decision and a leap. Every channel also has its own Pricing page. Listing by listing, it sets your figure beside the one the marketplace last reported — so a disagreement reaches you before it reaches your customer. Every listing lands in exactly one of the four cards along the top. Out of sync means the two disagree, and the difference column shows by how much. In sync is the opposite, with the two figures matching exactly. Channel price unknown is the marketplace staying silent. And not priced means SKU.io has no price for that listing at all, so there is nothing to compare and nothing to send. Every one of those cards is also a filter — click Out of sync, and the table narrows to just the listings that disagree, each gap spelled out in both dollars and percent. That comparison is only as fresh as the last time the channel reported its prices. Fetch from Amazon re-reads the current prices from the marketplace, so what you are looking at is what Amazon says right now rather than what it said this morning. It runs in the background and you can leave the page. One thing about that change limit surprises people. It compares against the price you last sent, and a refused price is never sent — so the same move is refused again on every later run. When a large change is deliberate, raise the limit for a single run from the arrow beside Push, and your saved limit is left untouched. The guardrails column answers a question the settings page cannot: which rules govern this particular listing. Most say channel, meaning they follow what you configured earlier. Any single listing can carry an exception of its own instead, and where it does, that exception replaces the channel's rules for that one listing. Open one and the important detail is at the top. An exception replaces the whole set, not the one field you came to change — a floor left at none is switched off for that listing rather than falling back to the channel. The same dialog sets who owns the price and which tier supplies it, so one listing can be handled differently without leaving the page. The exceptions tab is the answer to a question that gets harder as a catalogue grows: what are we doing that is not the default. Every exception on the channel, the values each one sets, and its author. If a price is behaving oddly, this is the shortest route to the rule responsible. After a push, the run history tells you what happened to every listing. Not just how many succeeded — which ones were refused, and by which rule. So open one of them up, and read what it actually did — the whole run, decision by decision. Every single listing it touched is accounted for, one row each. A blocked row names the guardrail that refused it, with the numbers, so you can judge where the fault really lies. A failed row carries the marketplace's own reply.

Last verified: