Integration Case Study

Fixing Amazon listing issues before the listing goes dark

Amazon publishes listing issues as they happen — a price out of bounds, a missing attribute, a restriction that makes an item unsellable. Finding out is not the hard part. The hard part is deciding, in the moment a notification lands, which issues warrant an automatic correction, which need a person, and which correction is destructive enough that it has to be right the first time.

Client
Book-inventory & resale operations platform
Scope
Amazon SP-API listing-issue automation, backend
Delivered
2026 · running in production
Ruby on RailsAmazon SP-APIAWS EventBridgeAmazon SNSSidekiqPostgreSQL
Summary

At a glance

Catalogue covered
~40,000
SKUs listed across both marketplaces. Approximate and rounded on purpose.
Remediation workflows
5–6
One per issue class Amazon reports, each with a deterministic correction behind it.
Detection
from Spot checks to Push
Amazon emits the issue and the application is subscribed, rather than sweeping on a timer.
Notification path
EventBridge
Amazon → an EventBridge bus in the client's AWS account → SNS → the app's webhook endpoint.
Redelivered notifications
Deduped
An idempotency ledger keyed per marketplace and event, because SNS delivers at least once.
Unmapped issue codes
To a human
A code with no workflow behind it is surfaced, never guessed at.

Every figure above describes the system as built, and the catalogue figure is deliberately approximate. The claim here is not a percentage — it is that listing issues are now acted on when Amazon reports them rather than when someone next thinks to look, and that the line between what gets corrected automatically and what gets escalated is drawn explicitly rather than by accident.

Context

A broken listing does not announce itself to anyone watching

Amazon listing health degrades quietly. A price drifts outside what the marketplace will accept for an ASIN, an attribute Amazon requires goes blank, the account loses permission to offer an item. The listing stops appearing or stops winning the buybox, and unless somebody happens to open Seller Central and check that SKU, the first visible signal is a dip in orders that nobody can explain.

Across a catalogue of roughly 40,000 SKUs on two marketplaces, checking by hand is not a strategy. It does not scale past a few hundred listings and it never reaches the long tail, which is exactly where a suppressed item can sit unnoticed for weeks.

Amazon does publish this. The question was never how to find out — it was what to do in the moment you are told.

Why the interesting problem is downstream of the notification

Subscribing to listing-issue notifications is a configuration exercise. What arrives is a stream of machine-readable complaints about individual SKUs, and every one of them raises the same three questions: does this actually mean the listing has stopped selling, is there a correction I can apply without a human looking at it, and is that correction safe to apply automatically?

Get the last one wrong and the automation becomes the problem. On Amazon a confident wrong fix can suppress a healthy listing, and one of the legitimate corrections is taking the listing down on purpose. This is not a system where the worst case is a stale row in a table.

Approach

Subscribe, route on severity, dispatch on the issue code

The path a notification takes

Amazon's listing-issue notifications are delivered onto an EventBridge bus inside the client's own AWS account, fanned out through SNS, and posted to a webhook endpoint on the application. Each notification names one SKU and the issues currently attached to it. There is no polling and no report to wait on: the application learns about a problem because Amazon pushed it, not because a scheduled job came round again.

The endpoint's only job is to accept the notification, record it, and hand it to a background job. Everything that talks back to Amazon happens in Sidekiq, so a slow SP-API call or a rate limit never turns into a failed delivery and a retry storm at the edge.

Severity routes the notification, it does not filter it

Every issue carries a severity, and severity decides which path the notification takes rather than whether it is worth keeping. An error is the serious case: it means the listing is suppressed or on its way there, and that is what puts the SKU onto the corrective path. A warning is a real signal about a listing that is still selling, and it is handled on its own terms rather than being pushed through the same corrective machinery.

The distinction matters because the two deserve different urgency and different consequences. Treating everything as an error spends SP-API calls correcting listings Amazon has not actually stopped showing; treating everything as a warning means the suppressions sit in a queue nobody drains.

A small registry of workflows, keyed by Amazon's issue code

Once a SKU is on the corrective path, the issue code Amazon supplies is the dispatch key. The application holds five or six remediation workflows, each one bound to an issue class with a deterministic remedy, and the code selects which runs. If an incoming code maps to a workflow, that workflow runs and submits the corrective update through the SP-API. If it does not, the notification is surfaced for a person rather than run through a generic best-effort fix.

That registry is deliberately small. Its size is not a limitation to be grown out of — it is the set of issue classes where the correct action is genuinely mechanical, and adding a workflow means having first established that the remedy is unambiguous.

The issue classes with a remediation workflow behind them, and what each workflow does.
Issue classWhat Amazon is reportingAutomated response
Price too highThe offer price is above what the marketplace will accept for that itemSubmit a corrected price
Price too lowThe offer price is below the allowed floorSubmit a corrected price
Missing priceThe listing carries no price at allSubmit the missing price
Missing catalogue dataA required attribute is absent from the listingResubmit the full listing payload
Listing restrictionThe account is not permitted to offer this itemTake the listing down
Anything unmappedAn issue code with no workflow behind itSurfaced for a person — nothing is guessed at

Three separate issue codes converge on the same remedy, which is the point of dispatching on the code rather than on the message: high, low and missing are three different complaints from Amazon about one field, and the workflow that answers all three is the same one. The restriction case is the outlier — the correct response to you may not sell this is to stop offering it, so the fix removes a live listing on purpose.

Guardrails

What keeps an automatic fix from becoming the outage

Every workflow here mutates a live listing on a marketplace the client sells on. That changes what the failure modes cost, and three properties exist specifically because of it.

Never acting on the same notification twice

SNS delivers at least once, so a redelivered notification is a certainty rather than an edge case. In a read-only pipeline a duplicate costs you a double-counted row; here it re-submits a price change or repeats a takedown against a listing that has already been corrected. Processing is guarded by an idempotency ledger keyed per marketplace and event, with explicit outcomes for a duplicate replay and for a genuinely stale event, so a redelivery is recorded and skipped rather than silently re-run.

Verifying the fix, not the response code

An accepted SP-API submission is not a completed one. A request can be acknowledged and still fail downstream, so each workflow checks that the listing actually changed rather than treating a success response as proof. Without that step the system reports a listing as repaired while it is still suppressed — which is worse than never having reported on it, because it removes the SKU from the list a person would otherwise have looked at.

The third is where the credentials live. Each company's marketplace credentials sit in a per-company encrypted integration store rather than in global configuration, and if a marketplace is not connected the workflow raises a clear not configured signal and stops for that marketplace. It never falls back to a global value, because a fallback would quietly act on one tenant's listings with another tenant's credentials the moment a row was missing.

Field Notes

Findings worth writing down

Things that cost real time, or would have cost real money, written down so the next SP-API integration does not rediscover them.

Dispatch on Amazon's issue code, never on the message text

The human-readable issue message is copy — it gets reworded, localised and expanded without notice. The issue code is the stable contract. Keying a workflow registry on the code means an Amazon wording change is a non-event; keying it on the text means the automation silently stops recognising a problem it used to fix, and nothing fails loudly enough to notice.

Severity is a routing decision, not a filter

An error means the listing is suppressed or heading there; a warning is a real signal about a listing that is still selling. Collapsing the two in either direction is expensive — treat everything as an error and you spend API calls correcting listings Amazon has not stopped showing, treat everything as a warning and the suppressions accumulate unattended.

SNS is at-least-once, and here a duplicate is a second write

Redelivery is guaranteed to happen eventually. When the handler only reads, a duplicate costs a wrong count; when the handler submits a price change or takes a listing down, a duplicate is a second live mutation. Idempotency has to be a ledger with recorded outcomes, not an assumption that the same input produces the same result.

Submitting a fix is not the same as the fix taking

An accepted SP-API request can still fail downstream, so the workflow has to verify the listing actually changed rather than trust the response. Skipping that turns a repaired-listing report into a false negative on the operator's worklist, which is the one failure mode worse than no automation at all.

Not every issue code deserves a workflow

The temptation with an unrecognised code is a generic fallback that resubmits everything and hopes. On Amazon that is how a confident automation suppresses a healthy listing. An unmapped code should surface to a person; the registry stays small on purpose, and a new workflow is earned by establishing that its remedy is unambiguous.

One of the correct fixes is destructive

The right answer to a listing restriction is to take the listing down — the automation deliberately removes a live offer. That workflow needs at least as much certainty behind it as the ones that restore a listing, because its failure mode is not an unfixed problem, it is revenue removed by the thing that was supposed to protect it.

Caveats

Reading this honestly

The figures here describe the system as built: the catalogue it covers, the number of remediation workflows, the shape of the notification path. None of them is a performance benchmark. There is no measured time-to-remediation on this page and no count of listings recovered, because neither was instrumented — the honest claim is that issues are acted on when Amazon reports them instead of when someone next looks, not a quantified improvement over the old behaviour.

The single highest-value metric to add next is a count of notifications received, auto-resolved and escalated per week. That is what would turn a capability statement into a measured one, and it is a small amount of work on top of a ledger that is already recording every event.

The client is unnamed and the catalogue figure is approximate and rounded deliberately rather than reported exactly. The marketplaces are not named, and nothing here describes a live deployment's topology, endpoints or credentials. A case study should not double as a disclosure of another business's operations.

Closing

What actually mattered

The easy version of this integration subscribes to the notifications and forwards them to somebody's inbox, which moves the problem rather than solving it. The work that mattered was everything after the notification lands: routing on severity so a suppression and a warning are not treated alike, dispatching on Amazon's stable issue code so the automation survives Amazon rewording its own messages, and keeping the workflow registry small enough that every automatic action has a remedy nobody has to think about.

The result is that a listing problem on a catalogue of roughly 40,000 SKUs is corrected in the ordinary case without anyone opening Seller Central, and escalated in the unusual one — with the line between those two drawn deliberately, because the cost of guessing wrong is a healthy listing taken off sale.

Back to all work