One Abstraction, Four Incompatible Realities #
Every multi-marketplace integration starts with the same reasonable idea: write one get_access_token(account) and let each marketplace plug in behind it. Then you discover that Etsy invalidates your stored credential on every call, Walmart has no refresh token at all, and eBay wants an opaque alias where a URL should go.
All four describe themselves as OAuth 2.0. The differences that matter aren't in the spec — they're in who owns the credentials, whether the refresh token rotates, and how long anything lasts. Get those three wrong in your schema and you'll be rewriting the account table six months in.
| Amazon SP-API | Etsy v3 | Walmart | eBay | |
|---|---|---|---|---|
| Grant type | LWA auth code | Auth code + PKCE | Client credentials | Auth code, no PKCE |
| App credentials | One shared app | One shared app | Per seller | One shared app |
| Access token | 1 hour | 1 hour | ~15 minutes | 2 hours |
| Refresh token | Long-lived, static | 90 days, rotates | None | ~18 months, static |
| Redirect target | Your URL | Your URL | N/A | RuName alias |
| Approval needed | Yes, roles | Above 5 shops | No | Keyset only |
Amazon: One App, Roles, and a Second Token for PII #
Amazon's Login with Amazon flow gives you a long-lived refresh token per selling partner that you exchange for a one-hour access token. Mechanically it's the simplest of the four to keep alive: store it once, mint access tokens forever.
The complexity sits elsewhere. Amazon gates data by role, applied at both the developer-profile level and the individual application level, and buyer PII needs an entirely separate token minted per call. If your integration returns null where a buyer name should be, that's the roles model talking — see the Restricted Data Token flow and why SP-API returns 403.
Setup reference: Amazon's connecting guide.
Etsy: PKCE, and the Rotation Race That Will Bite You #
Etsy is the only one of the four requiring PKCE: generate a code_verifier, send code_challenge = base64url(sha256(verifier)) with code_challenge_method=S256, and present the verifier at exchange time.
But the operationally dangerous part is rotation. Etsy's refresh token lives 90 days and rotates on every refresh — each refresh returns a new one and invalidates the old. That has two consequences most teams learn the hard way:
- You must persist the new refresh token atomically, every time. Crash between "received new token" and "committed to database" and that shop is disconnected permanently. Only a human re-consent brings it back.
- Concurrent refreshes cancel each other. Two overlapping syncs of the same shop each refresh, and the second invalidates the first's token. A scheduled sync racing a manual "sync now" is enough to do it.
The fix is boring and effective: cache the access token with its expiry and only refresh inside a small window before it expires, then serialise refreshes per account with a lock. Do that and the 90-day chain self-renews indefinitely — a shop syncing hourly never needs to log in again.
Walmart: No Refresh Token, and Headers Instead of Authorization #
Walmart is the outlier and, ironically, the easiest to operate. It uses plain client credentials: POST your key pair, get a ~15-minute access token, repeat. No browser, no consent screen, no PKCE, no refresh token, no approval process — keys generated in the portal work immediately.
The catch is that credentials are per seller. There is no shared app, so every seller you onboard hands you their own Client ID and Secret, and your schema needs an encrypted credential pair on each account row rather than one pair in config.
The other thing that catches people is that Walmart doesn't use the standard Authorization header for the bearer:
WM_SEC.ACCESS_TOKEN: <token> # the bearer, in Walmart's own header
WM_QOS.CORRELATION_ID: <fresh UUID> # regenerate per request
WM_SVC.NAME: Walmart Marketplace
Accept: application/json # or you may get XML back
And do not confuse the current token scheme with the deprecated signature scheme (WM_SEC.AUTH_SIGNATURE, WM_CONSUMER.*) — a lot of older blog posts and Stack Overflow answers still show the signature version. Current docs: Walmart Marketplace authentication.
eBay: Auth Code Without PKCE, and the RuName #
eBay sits between Amazon and Etsy. It's an authorization-code grant like Etsy but without PKCE, and its refresh token is static like Amazon's — roughly 18 months, no rotation, so no atomic-persist problem.
Its one genuine oddity is that redirect_uri takes a RuName, an alias registered in the portal, rather than your callback URL. Sending the URL gets you a redirect_uri error that looks like a configuration mistake and isn't. That, plus a legal-address gate blocking RuName creation, is covered in detail in the eBay OAuth walkthrough.
What This Means for Your Schema #
Three questions decide the shape of your account table, and the answers differ per marketplace:
- Are credentials shared or per-account? Amazon, Etsy and eBay: shared app credentials in config, per-account token on the row. Walmart: encrypted credential pair on every row. Build for both from day one — a nullable per-account override column costs nothing and saves a migration.
- Does the stored secret change during normal operation? Only Etsy. That single "yes" is what forces atomic writes and per-account refresh locking. Design the write path around the marketplace that rotates, and the others come along for free.
- Does the credential expire on a calendar, independent of use? eBay at ~18 months, Etsy at 90 days of inactivity. Store the expiry as a real column and surface it in your UI — a token that dies quietly is an outage nobody notices until a seller asks where their orders went.
Everything above the token layer — throttling, retries, incremental windows — can be genuinely shared. Just don't try to make the token layer itself uniform. It isn't.
Building a multi-marketplace sync? The auth models are the first difference you meet, not the last — see how the same four APIs handle personalisation data, or get help designing the integration.
FAQ #
Which marketplace APIs require PKCE?
Of the four major ones, only Etsy's Open API v3 requires PKCE. Amazon SP-API, Walmart and eBay do not — Amazon and eBay use plain authorization-code grants with client secrets, and Walmart uses client credentials.
Does Amazon SP-API's refresh token expire?
It is long-lived and does not rotate on refresh. It is invalidated if the selling partner revokes your app's authorisation or if you re-list the application, which forces sellers to re-authorise.
Why does my Etsy integration randomly stop working?
Almost always the rotating refresh token. Etsy issues a new refresh token on every refresh and invalidates the previous one, so either a failed write or two concurrent refreshes will orphan the shop. Cache access tokens and serialise refreshes per shop.
Does Walmart's Marketplace API have a refresh token?
No. Walmart uses OAuth 2.0 client credentials — you exchange a per-seller Client ID and Secret for a roughly 15-minute access token whenever you need one. There is nothing to rotate or persist beyond the credential pair itself.
Can I use one set of app credentials for all sellers?
For Amazon, Etsy and eBay, yes — one registered application with a per-seller token. For Walmart, no: each seller generates their own Client ID and Secret in their own portal account.
Related guides
Marketplace APIs
eBay OAuth: RuName Is Not a Redirect URI (Connecting a Seller Account)
Your eBay consent URL keeps failing with an invalid redirect_uri, and the value you're sending looks perfectly correct. It is — it's just the wrong kind of value. eBay expects a RuName, not your callback URL. Here's the full flow for connecting one seller account: keyset, the legal-address gate, scopes, token exchange, and the first getOrders call.
Read guide →Marketplace APIs
Getting Personalisation Text Out of Amazon, Etsy and eBay (Three APIs, Three Answers)
A buyer typed an engraving into a product page and your fulfilment team needs those exact characters. Every marketplace delivers them differently — Amazon hides them in a ZIP behind a signed URL, Etsy puts them inline, and eBay's Fulfillment API doesn't return them at all. Here's where to find them, and the trap in Amazon's payload that silently loses text.
Read guide →Marketplace APIs
No Marketplace Gives You a Real Buyer Phone Number (What to Do Instead)
Your carrier API rejects the shipment because the consignee phone is missing, and the order payload simply doesn't contain one. That's not a bug in your integration — Etsy and Walmart don't return a buyer phone at all, and Amazon's is a relay number. Here's what each marketplace actually gives you and how to satisfy the carrier without inventing data.
Read guide →Don't want to build this yourself?
I set this up for sellers and agencies every week. Book a free 30-minute audit of your Amazon data & PPC setup — you'll leave with a plan either way, whether we work together or not.