Self-hosted infrastructure for running eBay selling agents: a compliant production API connection, OAuth token management, and (soon) photo-to-listing and repricing automations. Built to be cloned, configured, and deployed on any Docker host — a Proxmox LXC, a VPS, a Raspberry Pi, or a laptop.
Anyone can register a free eBay developer account, but two things block almost every new seller-developer from using the production APIs:
- The compliance wall — every production app must implement eBay's Marketplace Account Deletion/Closure notification endpoint (challenge + signed event receiver) at a public HTTPS URL. Until it's registered and verified, the app is flagged Non Compliant and production OAuth consent is refused. This repo ships the endpoint as a container plus a Cloudflare-Tunnel recipe that works behind any home NAT — no port forwarding, no static IP.
- No refresh tokens from the portal — the developer portal's token page mints short-lived (~2h) user tokens with no refresh token, and the OAuth consent dance (RuName, scopes, code exchange) is only documented in fragments. This repo ships an interactive helper that performs the full flow and lands you a durable refresh token for your agents.
| Path | What it is |
|---|---|
app/main.py |
FastAPI Marketplace Account Deletion endpoint (challenge GET + event POST) |
Dockerfile / docker-compose.yml |
The endpoint container + optional cloudflared tunnel |
env.example |
Template for .env |
scripts/oauth_setup.py |
Interactive OAuth flow: validate keys → consent URL → exchange code → verify + print durable refresh token |
scripts/check_connection.py |
Post-setup smoke test: token refresh + live API calls |
scripts/listings_snapshot.py |
Pull your active listings (Trading API) as JSON |
- Register at https://developer.ebay.com (any eBay account works).
- Application Settings → create an application → copy the App ID (Client ID) and Cert ID (Client Secret). Dev ID is also shown.
- Still in Application Settings, add an eBay Redirect URL (RuName): click Add eBay Redirect URL → Auth accepted URL → give it any HTTPS URL you control (it is only an alias; the request never needs to reach it). Enable OAuth for it.
- User Tokens (eBay Sign-In) page → Select OAuth Scopes → check the
sell scopes you need (inventory, account, fulfillment, marketing,
analytics, finances, payment dispute, item draft, identity).
Production hard-fails the consent flow with
invalid_scopeif you request any scope you did not pre-check here.
git clone https://github.com/YOURUSER/ebay-ops.git && cd ebay-ops
cp env.example .env
# edit .env: EBAY_VERIFICATION_TOKEN (32-80 chars YOU invent),
# EBAY_ENDPOINT_URL (the public URL you will register)
docker compose up -d --build
curl http://localhost:8790/health # -> {"ok":true}Easiest: a Cloudflare Tunnel (free, no open ports).
- Cloudflare dashboard → Zero Trust → Networks → Tunnels → create one
(Cloudflared type), copy its token into
.envasCF_TUNNEL_TOKEN. - Route the tunnel's public hostname to your service:
- Dashboard way: Public Hostname tab → subdomain/domain of your choice →
service
HTTP→ebay-compliance:8000. - The hostname you route MUST match
EBAY_ENDPOINT_URLcharacter-for-character.
- Dashboard way: Public Hostname tab → subdomain/domain of your choice →
service
docker compose --profile tunnel up -d
Then on developer.ebay.com → Alerts & Notifications → delivery method Marketplace Account Deletion → enter the same endpoint URL and the same verification token → Save → Send Test Notification. Your app flips to Compliant.
python3 scripts/oauth_setup.py --env sandbox # or --env productionThe script validates your Cert ID, prints a consent URL, waits for you to
paste the redirect URL after approving, exchanges the code, verifies the
refresh token with a live API call, and writes everything to .env.
python3 scripts/check_connection.pyExpect order and inventory counts from your real account.
- Sold/completed price data is not available via API for normal
developers: the Finding API (incl.
findCompletedItems) was decommissioned 2025-02, and Marketplace Insights is restricted to approved partners. Repricing has to use active-market signals (Browse API asking prices, watchers) plus eBay's Promoted Listings Recommendation API (ad suggestions only — no price recommendations), and Terapeak (Seller Hub web UI) manually. - The portal's "Get a User Token Here" button mints an Auth'n'Auth SAML token
even when the OAuth radio is selected — it returns 403 on REST Sell APIs.
Use
scripts/oauth_setup.pyinstead. - Sandbox quirks: token responses return an empty
scopefield (the token still carries scopes);sell.accountmay be denied for fresh sandbox users ("not eligible for Business Policy") — that is a profile issue, not auth. - Keep every credential in
.env(git-ignored). Never commit keys.
- Compliance endpoint + tunnel recipe
- OAuth setup + connection smoke test
- Listings snapshot
- Photo-to-draft listing pipeline (item ID → specs → priced draft offer)
- Repricing watcher with decision cards
- Buyer-message triage
MIT — see LICENSE. Not affiliated with or endorsed by eBay Inc. You are responsible for complying with eBay's API License Agreement and staying within rate limits.