eBay Direct Integration
JewelTrak’s eBay integration uses the Inventory API + Account API to push listings directly from inventory data — no CSV uploads, no copy-paste. An item’s eBay category and item specifics are entered once, in the same section the Frooition tab uses, and go out whichever way the shop lists.
Supports all 5 inventory families: jewelry, watches, diamonds, colored stones, pearls.
Before you start — eBay developer keys
Connecting eBay needs platform-level credentials that you (the JT operator) provision once and add to Vercel env vars. This is a one-time admin task, separate from the per-tenant connect flow.
- Sign in at developer.ebay.com (or create a free account)
- My Account → Application Keysets → Create a keyset
- eBay issues a Sandbox keyset + a Production keyset. Each has:
- App ID (Client ID)
- Cert ID (Client Secret)
- For each keyset, User Tokens → Add eBay Redirect URL (RuName):
- Redirect URL:
https://app.jeweltrak.com/settings/integrations/ebay/callback - Privacy policy URL: your privacy policy
- Redirect URL:
- Save. eBay generates a RuName string like
JewelTrak-JewelTrak-PRD-xxxxxxxxx. - Paste into Vercel environment variables:
EBAY_CLIENT_ID(App ID)EBAY_CLIENT_SECRET(Cert ID)EBAY_RU_NAME(RuName string)EBAY_SANDBOX(truefor sandbox testing,falsefor production)
Tenants see an amber “eBay developer keys pending” notice on the integration card until these env vars are populated. The Connect button is disabled until then.
Connecting eBay (tenant flow)
Once the keys are in place:
- Settings → Integrations → eBay → Connect eBay
- You’re redirected to eBay to log in with the seller account and grant JewelTrak permission to manage inventory and orders
- eBay bounces back to JewelTrak with a success banner
- Token + refresh token are saved server-side; access tokens auto-refresh in the background (eBay access tokens last ~2 hours, refresh tokens last 18 months)
Post-connect setup — Business Policies + fulfillment location
eBay’s Inventory API requires every listing to reference:
- A Shipping Policy ID
- A Payment Policy ID
- A Return Policy ID
- A Merchant Location Key (your fulfillment address)
Click Load my eBay choices on the integration card. JT pulls these from your eBay account in one request and populates dropdowns. Pick one of each and Save eBay Config.
“Your eBay account hasn’t turned on Business Policies yet.” Some eBay accounts, new ones especially, have never switched Business Policies on, and eBay won’t return any policies until they do. Click Turn on Business Policies: JewelTrak asks eBay to switch it on, and that’s the only thing it changes on your eBay account. eBay can take a little while to finish; if Load my eBay choices still says it’s off, try again later. If you have no policies yet, create a shipping, payment and return policy in eBay, then load again. A policy type with none on your account shows a note and a link instead of an empty list.
Ship-from location. eBay only accepts this location through a connected program like JewelTrak; there’s no page on eBay’s website to make one. Click Add your ship-from location. The form starts with your store’s address from JewelTrak; fix anything that’s off and click Create on eBay. It’s created on your eBay account and selected straight away.
If any are missing, JT shows the per-item Publish button as disabled with a “finish setup” link.
Per-item listing — the eBay sub-tab
On any inventory item (jewelry/watch/diamond/colored stone/pearl), open Sales Channels → eBay sub-tab.
The tab has two parts.
Category and item specifics come first. This is the same section as Sales Channels → Frooition, saved to the same place, so a shop that uses both enters them once. JewelTrak picks a category from the item (a Ring goes to Fine Jewelry > Rings, a loose colored stone or pearl to Loose Gemstones) and fills in what it already knows; fill in the rest and click Save item specifics. Specifics eBay requires for that category are listed first and marked with a red *, and the section names any that are still empty. For a ring eBay requires Brand, Main Stone, Metal, Metal Purity and Ring Size; Publish to eBay stops with that list rather than letting eBay turn the listing down one missing specific at a time. The Frooition article walks through the section in detail.
The listing form below it has:
- Title — eBay’s 80-char hard cap, with a live remaining-character counter.
- Subtitle — 55-char cap. eBay charges $1.50 to use this (warned in the help text).
- Format — Fixed Price or Auction. Auction unlocks Starting Bid field.
- Buy It Now price — required for Fixed Price; the floor for Auction.
- Quantity — defaults to 1 (single-unique jewelry is the default model).
- Duration — Good ‘Til Cancelled for Fixed Price; 3/5/7/10 days for Auction.
- Best Offer — accept yes/no, plus optional auto-accept and minimum thresholds.
- Condition + Condition Description — required.
- Description — HTML body. Falls back to the inventory item Description if left blank.
Save keeps the listing form without publishing; it never changes the category or item specifics. Publish to eBay posts the listing live; the panel updates with the listing ID and timestamp.
Publish sends what is saved, so it stays greyed out until the item is ready, with the reason on the line under it: a category and every required specific saved in the section above, a title, a condition, a price, at least one photo (with a link to the General tab to add one), and no unsaved edits in the listing form.
A piece that is already live on eBay through Frooition (linked to JewelTrak) can’t be published from here, because that would put a second listing up for the same piece. The line under Publish says so and links to the live eBay item. End it with Retire Listing, or edit it on eBay.
Push flow (under the hood)
When you click Publish to eBay the handler does 3 sequential API calls:
createOrReplaceInventoryItem— PUT to eBay with title, description, aspects, image URLs, condition, quantity. Idempotent by SKU.createOffer— POST creating the offer record (category, price, business policies, fulfillment location).publishOffer— POST that turns the draft offer into a live listing. Returns the eBay listing ID.
Both successes and failures flow back into channel_listings. Failures stamp the LastError so the panel shows what went wrong on the next page render.
Auto-retire on sale
When JewelTrak inventory drops to QOH=0 (POS sale, void, scrap, memo issue, manual edit), the dispatcher fans out to every connected channel. For eBay this means the listing is withdrawn automatically. No more “available” listings for items already sold.
Re-listing on 0→1 is NOT automated — operator re-publishes manually to re-check pricing + description.
Photo changes update the listing
When you add a photo, delete one, choose a different main photo, or keep a worn-on-model photo on an item that JewelTrak listed on eBay, the eBay listing updates by itself within about 15 seconds. It keeps the same eBay item number. The main photo is always eBay’s first picture (the one shoppers see in search results). Several changes made back to back go to eBay as one update.
If the update fails, the eBay panel shows the reason, starting with “Photo update:“. Deleting every photo leaves eBay on the old pictures, because eBay won’t keep a listing with none.
Listings posted through Frooition and linked to JewelTrak are not updated this way. Send the new photos to eBay through Frooition.
Bulk push — coming Phase 1b
Per-item Publish is live today. Bulk publish from the inventory/watches/diamonds list pages is on the Phase 1b list.
Sandbox vs production
EBAY_SANDBOX=true routes auth + API calls to sandbox.ebay.com. Test there until your workflow is solid, then flip to production by:
- Setting
EBAY_SANDBOX=false - Swapping in Production credentials (a different App ID / Cert ID / RuName from the Production keyset)
- Redeploying Vercel
Each tenant must re-connect on the new environment — sandbox and production OAuth tokens are not interchangeable.
Phase 1b roadmap
Items shipping after the first round of live tenant testing:
- Quantity sync into the dispatcher (helper exists, not yet wired)
- Bulk publish + bulk retire from list pages
- Description auto-derivation from inventory fields when BodyHtml is blank
- Frooition MFL import path (parse a tenant’s existing Frooition exports into ebay_settings)
Phase 2 — inbound orders
Not yet built. When a sale happens on eBay (vs in JT), eBay sends an order webhook that JT will turn into an invoice with SourceChannel='ebay'. The fulfillment-on-finalize trigger then pushes shipment back to eBay so the buyer sees Fulfilled status. Same pattern Shopify uses today.
Troubleshooting
- Connect eBay button is disabled / “developer keys pending” — Vercel env vars not populated. Admin task; one-time setup.
- Token exchange fails after eBay redirect — Sandbox vs Production mismatch. Check
EBAY_SANDBOXenv var against the keyset’s environment. - “Your eBay account isn’t set up to sell yet” — eBay needs the account’s seller registration finished (payout and identity details) before anything can be listed. The message includes eBay’s registration link; finish it there, then publish again.
- “eBay won’t list this without: …” — those required specifics are empty. Fill them in the item’s eBay section, save it, and publish again.
- Publish button is disabled — One of: not connected, business policies not selected, fulfillment location not chosen, no category saved, or the title, condition or price is empty, or the piece is already live on eBay through Frooition. A category JewelTrak suggested isn’t saved until you click Save item specifics.
- “Authorization required” on listing changes — Your eBay refresh token expired (18-month window). Re-Connect on the integration card to issue a new one.
- “eBay needs reconnecting” banner (Listings page) or “Reconnect needed” badge (Integrations hub) — JewelTrak detected an authentication failure on a push or reconcile (usually the expired refresh token above). Pushes keep failing until you click Reconnect and re-authorize; the flag clears on the next successful push.