To integrate Replit with the eBay API, register a developer app at developer.ebay.com, store your App ID (Client ID) and Client Secret in Replit Secrets (lock icon π), then call eBay's OAuth 2.0 token endpoint from your server to get an access token. Use the token to query the eBay Browse API for listings or the Sell API to manage your listings β all from Node.js or Python running on your Replit backend.
Why Integrate eBay API with Replit?
eBay is the world's largest auction and fixed-price marketplace, hosting over 1.7 billion live listings. The eBay API opens up this inventory for programmatic access: you can search products, retrieve item details and prices, check seller ratings, monitor auction end times, and β with seller-level access β create and manage your own listings. Building this functionality on Replit lets you run price monitors, inventory sync tools, and marketplace analytics without maintaining local servers.
eBay's modern REST API (released 2016 onward) is organized into logical APIs: Browse API for buyers searching the marketplace, Sell API for listing and order management, Taxonomy API for category data, and Analytics API for seller performance. The Browse API uses simple OAuth Client Credentials (no user login required) making it the easiest entry point for most Replit projects. The Sell API requires a user OAuth token from a seller's eBay account.
Common Replit and eBay API use cases include: price comparison tools that monitor listing prices over time, dropshipping tools that check eBay pricing before placing supplier orders, inventory management systems that sync stock levels between eBay and other platforms, and competitor research tools that track how similar products are priced across the marketplace.
Integration method
The Replit-eBay API integration uses OAuth 2.0 Client Credentials flow to obtain an application-level access token for public operations like Browse API searches, or the Authorization Code flow for user-level operations like Sell API listing management. Your App ID and Client Secret are stored in Replit Secrets and used server-side to request tokens from eBay's OAuth endpoint. All API calls are made from your Replit backend to keep credentials secure.
Prerequisites
- An eBay developer account at developer.ebay.com (free to register)
- An eBay application created in the Developer Portal β this gives you your App ID (Client ID) and Client Secret
- A Replit account with a Node.js or Python Repl
- Basic understanding of OAuth 2.0 Client Credentials flow
Step-by-step guide
Register an eBay Developer App
Register an eBay Developer App
Go to developer.ebay.com and sign in with your eBay account (or create a free developer account). Navigate to My Account β Application Keys (or Application Access Keys). Click 'Create a Keyset'. Give your application a name (e.g., 'Replit Price Monitor') and choose the environment β start with 'Sandbox' for testing, then create a separate keyset for 'Production'. eBay generates three keys: - App ID (Client ID): the public identifier of your application - Dev ID: your developer account ID (used in older API calls) - Cert ID (Client Secret): the secret used to obtain OAuth tokens You will also need to configure at least one RuName (Redirect URL Name) in the application settings if you plan to use the Authorization Code flow for seller operations. For Browse API (read-only marketplace access), the Client Credentials flow does not require a RuName. Note: Sandbox and Production are separate environments with separate keys. Sandbox data is synthetic β it does not reflect real eBay listings. Use Production keys to access real marketplace data, but be aware that API calls against Production count toward your daily call limits.
Pro tip: eBay's Developer Program enforces daily API call limits per application. Sandbox limits are lower than Production. Cache API responses in memory or a database to avoid hitting limits during development.
Expected result: You have an App ID (Client ID) and Cert ID (Client Secret) for your eBay application in either Sandbox or Production environment.
Store eBay Credentials in Replit Secrets
Store eBay Credentials in Replit Secrets
Click the lock icon (π) in the Replit sidebar to open the Secrets panel. Add the following secrets: EBAY_CLIENT_ID β your App ID (Client ID) EBAY_CLIENT_SECRET β your Cert ID (Client Secret) EBAY_ENVIRONMENT β 'sandbox' or 'production' The base OAuth URL for each environment: - Sandbox: https://api.sandbox.ebay.com - Production: https://api.ebay.com Both the Client ID and Client Secret are needed to obtain OAuth tokens. The Client Secret in particular is sensitive β it should never appear in frontend code or Git commits. For eBay's Client Credentials flow, the token endpoint requires a Basic auth header where the username is your Client ID and the password is your Client Secret, base64-encoded. In Node.js: Buffer.from(`${clientId}:${clientSecret}`).toString('base64'). In Python: base64.b64encode(f'{client_id}:{client_secret}'.encode()).decode().
Pro tip: Create two separate Replit projects (or two separate Secret groups) for sandbox and production eBay credentials. Avoid switching credentials in the same project to prevent accidental production calls during development.
Expected result: EBAY_CLIENT_ID, EBAY_CLIENT_SECRET, and EBAY_ENVIRONMENT are stored in Replit Secrets and accessible via process.env (Node.js) or os.environ (Python).
Obtain an OAuth Access Token (Node.js)
Obtain an OAuth Access Token (Node.js)
eBay uses OAuth 2.0. For read-only marketplace operations (Browse API, Taxonomy API), use the Client Credentials flow β it requires only your App ID and Client Secret and produces an application-level token. No user login is needed. Tokens expire after 7200 seconds (2 hours). Your code should cache the token and only request a new one when the current one is near expiry. The code below implements a simple token cache with automatic refresh. The Browse API also requires a Marketplace ID header (X-EBAY-C-MARKETPLACE-ID) to specify which eBay site to search (e.g., EBAY_US, EBAY_GB, EBAY_DE).
1// ebay-auth.js β eBay OAuth token manager2const BASE_URL = process.env.EBAY_ENVIRONMENT === 'production'3 ? 'https://api.ebay.com'4 : 'https://api.sandbox.ebay.com';56let tokenCache = { token: null, expiresAt: 0 };78async function getAccessToken() {9 // Return cached token if still valid (with 60s buffer)10 if (tokenCache.token && Date.now() < tokenCache.expiresAt - 60000) {11 return tokenCache.token;12 }1314 const clientId = process.env.EBAY_CLIENT_ID;15 const clientSecret = process.env.EBAY_CLIENT_SECRET;16 if (!clientId || !clientSecret) {17 throw new Error('EBAY_CLIENT_ID or EBAY_CLIENT_SECRET not set in Secrets');18 }1920 const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');21 const response = await fetch(`${BASE_URL}/identity/v1/oauth2/token`, {22 method: 'POST',23 headers: {24 'Authorization': `Basic ${credentials}`,25 'Content-Type': 'application/x-www-form-urlencoded'26 },27 body: 'grant_type=client_credentials&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope'28 });2930 if (!response.ok) {31 const error = await response.text();32 throw new Error(`eBay token error ${response.status}: ${error}`);33 }3435 const data = await response.json();36 tokenCache = {37 token: data.access_token,38 expiresAt: Date.now() + (data.expires_in * 1000)39 };4041 return tokenCache.token;42}4344// Browse API: search eBay listings45async function searchListings(query, limit = 10, marketplaceId = 'EBAY_US') {46 const token = await getAccessToken();47 const params = new URLSearchParams({ q: query, limit });48 const url = `${BASE_URL}/buy/browse/v1/item_summary/search?${params}`;4950 const response = await fetch(url, {51 headers: {52 'Authorization': `Bearer ${token}`,53 'X-EBAY-C-MARKETPLACE-ID': marketplaceId,54 'Content-Type': 'application/json'55 }56 });5758 if (!response.ok) {59 const error = await response.text();60 throw new Error(`eBay Browse API error ${response.status}: ${error}`);61 }6263 return response.json();64}6566module.exports = { getAccessToken, searchListings };Pro tip: The scope parameter in the Client Credentials request must match the API you are calling. 'https://api.ebay.com/oauth/api_scope' works for Browse API. Sell API requires additional scopes and a user OAuth token.
Expected result: getAccessToken() returns a JWT access token string. searchListings('bluetooth speaker') returns item summaries with title, price, and item URLs.
Build an eBay Search API Server with Express
Build an eBay Search API Server with Express
Wrap the eBay client in an Express server to expose a clean search endpoint. This lets other services query eBay data through your Replit app without needing access to eBay credentials. Install Express: npm install express Deploy this as an Autoscale deployment on Replit. Price trackers and search tools are on-demand workloads β they do not need a Reserved VM running 24/7.
1// server.js β eBay search API server2const express = require('express');3const { searchListings } = require('./ebay-auth');45const app = express();6app.use(express.json());78// GET /search?q=laptop&limit=20&marketplace=EBAY_US9app.get('/search', async (req, res) => {10 const { q, limit = 10, marketplace = 'EBAY_US' } = req.query;11 if (!q) {12 return res.status(400).json({ error: 'q (search query) is required' });13 }14 try {15 const data = await searchListings(q, parseInt(limit), marketplace);16 const items = (data.itemSummaries || []).map(item => ({17 title: item.title,18 price: item.price?.value,19 currency: item.price?.currency,20 condition: item.condition,21 itemId: item.itemId,22 url: item.itemWebUrl,23 seller: item.seller?.username,24 imageUrl: item.image?.imageUrl25 }));26 res.json({27 total: data.total || 0,28 query: q,29 items30 });31 } catch (err) {32 console.error('eBay search error:', err.message);33 res.status(500).json({ error: err.message });34 }35});3637const PORT = process.env.PORT || 3000;38app.listen(PORT, '0.0.0.0', () => {39 console.log(`eBay API server running on port ${PORT}`);40});Pro tip: Add caching for search results to reduce API calls and stay within eBay's daily call limits. Even a 5-minute cache on popular search terms dramatically reduces API usage.
Expected result: GET /search?q=laptop returns a JSON array of eBay listing summaries with price, condition, and item URLs.
Python Implementation
Python Implementation
For Python-based Replit projects, the requests library handles the eBay OAuth token request and Browse API calls cleanly. Flask provides the server layer. Install: pip install requests flask The Python version implements the same token caching pattern as Node.js to avoid requesting a new token on every API call.
1# app.py β eBay API server in Python2import os3import base644import time5import requests6from flask import Flask, request, jsonify78app = Flask(__name__)910BASE_URL = (11 'https://api.ebay.com'12 if os.environ.get('EBAY_ENVIRONMENT') == 'production'13 else 'https://api.sandbox.ebay.com'14)1516_token_cache = {'token': None, 'expires_at': 0}1718def get_access_token():19 if _token_cache['token'] and time.time() < _token_cache['expires_at'] - 60:20 return _token_cache['token']2122 client_id = os.environ['EBAY_CLIENT_ID']23 client_secret = os.environ['EBAY_CLIENT_SECRET']24 credentials = base64.b64encode(f'{client_id}:{client_secret}'.encode()).decode()2526 resp = requests.post(27 f'{BASE_URL}/identity/v1/oauth2/token',28 headers={29 'Authorization': f'Basic {credentials}',30 'Content-Type': 'application/x-www-form-urlencoded'31 },32 data='grant_type=client_credentials&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope',33 timeout=1034 )35 resp.raise_for_status()36 data = resp.json()37 _token_cache['token'] = data['access_token']38 _token_cache['expires_at'] = time.time() + data['expires_in']39 return _token_cache['token']4041def search_listings(query, limit=10, marketplace='EBAY_US'):42 token = get_access_token()43 resp = requests.get(44 f'{BASE_URL}/buy/browse/v1/item_summary/search',45 headers={46 'Authorization': f'Bearer {token}',47 'X-EBAY-C-MARKETPLACE-ID': marketplace48 },49 params={'q': query, 'limit': limit},50 timeout=1551 )52 resp.raise_for_status()53 return resp.json()5455@app.route('/search')56def search():57 q = request.args.get('q')58 limit = int(request.args.get('limit', 10))59 marketplace = request.args.get('marketplace', 'EBAY_US')60 if not q:61 return jsonify({'error': 'q parameter required'}), 40062 try:63 data = search_listings(q, limit, marketplace)64 items = [{65 'title': i.get('title'),66 'price': i.get('price', {}).get('value'),67 'currency': i.get('price', {}).get('currency'),68 'condition': i.get('condition'),69 'url': i.get('itemWebUrl')70 } for i in data.get('itemSummaries', [])]71 return jsonify({'total': data.get('total', 0), 'query': q, 'items': items})72 except requests.HTTPError as e:73 return jsonify({'error': str(e)}), 5007475if __name__ == '__main__':76 app.run(host='0.0.0.0', port=3000)Pro tip: eBay's Browse API sandbox uses synthetic test data. If your searches return zero results in sandbox, try simple single-word queries like 'phone' or 'shirt' β the sandbox catalog is limited compared to production.
Expected result: python app.py starts the Flask server. GET /search?q=phone returns eBay listing summaries with prices and URLs.
Common use cases
eBay Price Monitor and Tracker
Build a Replit server that accepts a search query, retrieves the current lowest Buy It Now price from eBay's Browse API, and stores the result with a timestamp. Schedule it to run hourly to track price trends for specific products or categories.
Build a Node.js Express server with a GET /price?query=iphone+14 endpoint that searches eBay's Browse API for the given query and returns the top 10 results with title, price, condition, and listing URL. Store EBAY_APP_ID and EBAY_CLIENT_SECRET in environment variables.
Copy this prompt to try it in Replit
Dropship Margin Calculator
Create a tool that takes a product search term, fetches current sold listings from eBay to determine realistic selling prices, and calculates profit margin after eBay fees and your cost of goods. Export results to CSV for bulk product research.
Write a Python script that takes a product keyword as input, fetches the top 20 eBay listings with prices using the Browse API, calculates the average and median sale price, deducts 12.9% eBay final value fee, and prints a margin table. Store credentials in environment variables.
Copy this prompt to try it in Replit
Multi-Marketplace Inventory Sync
Build a webhook receiver on Replit that listens for order events from other platforms and automatically updates eBay listing quantities using the Inventory API. This prevents overselling when the same product is listed on multiple channels.
Create a Node.js server with a POST /webhook/order endpoint. When an order arrives, call the eBay Inventory API to decrease the quantity of the matching item by the ordered amount. Store eBay OAuth tokens in environment variables and log every quantity update.
Copy this prompt to try it in Replit
Troubleshooting
HTTP 401 β 'Invalid access token' when calling the Browse API
Cause: The access token has expired (tokens last 2 hours) or the Authorization header format is wrong.
Solution: Ensure your code caches the token and refreshes it before expiry. Check that the Authorization header is formatted as 'Bearer {token}' with a space after 'Bearer'. Verify your Client Credentials grant was successful before attempting Browse API calls.
1// Check token expiry before calling API2if (Date.now() > tokenCache.expiresAt - 60000) {3 console.log('Token expired, refreshing...');4 await getAccessToken();5}HTTP 400 β 'Invalid client' when requesting the access token
Cause: The Base64-encoded credentials in the Authorization header are malformed, or the App ID or Client Secret contain errors.
Solution: Open Replit Secrets and copy your EBAY_CLIENT_ID and EBAY_CLIENT_SECRET again from the eBay Developer Portal to eliminate any copy-paste errors. Test the Base64 encoding separately to confirm it produces the correct output.
1// Test credential encoding2const encoded = Buffer.from(`${process.env.EBAY_CLIENT_ID}:${process.env.EBAY_CLIENT_SECRET}`).toString('base64');3console.log('Encoded credentials length:', encoded.length);Browse API returns empty itemSummaries array for a valid search query
Cause: You may be using Sandbox environment credentials, which have a limited catalog. Alternatively, the search query may not match any indexed items.
Solution: Check EBAY_ENVIRONMENT in Replit Secrets. If it is 'sandbox', try switching to 'production' (ensure you have production keys). Try broad single-word queries in sandbox first. Verify the X-EBAY-C-MARKETPLACE-ID header matches your target eBay site.
HTTP 429 β API call limit exceeded
Cause: Your application has exceeded eBay's daily API call limit for your application or developer account.
Solution: Add response caching for search queries (store results in memory with a TTL of 5-30 minutes). Check your API usage in the eBay Developer Portal. Apply for increased call limits if your application needs more throughput.
1// Simple in-memory cache for search results2const searchCache = new Map();3function cachedSearch(query, limit) {4 const key = `${query}:${limit}`;5 const cached = searchCache.get(key);6 if (cached && Date.now() - cached.timestamp < 300000) return cached.data;7 return null;8}Best practices
- Cache OAuth access tokens for their full 2-hour lifetime β requesting a new token for every API call wastes your daily token request quota
- Cache search results for at least 5-30 minutes to stay within eBay's daily API call limits and improve response times
- Store EBAY_CLIENT_SECRET in Replit Secrets and never log it or include it in HTTP responses
- Use the Sandbox environment with sandbox credentials during development β switch to Production secrets only when you are ready to go live
- Always specify the X-EBAY-C-MARKETPLACE-ID header to target the correct eBay regional site (EBAY_US, EBAY_GB, etc.)
- Validate and sanitize user-provided search queries before passing them to the eBay API to prevent unexpected results or parameter injection
- Deploy price-tracking and search tools as Autoscale deployments β they handle on-demand requests without requiring a persistent Reserved VM
- Request only the fields you need using the fieldgroups parameter to reduce response payload size and improve performance
Alternatives
The Etsy API is a better choice if your audience sells handmade, vintage, or craft items β Etsy's community and discovery features are tailored for that market.
AliExpress Open Platform API is better suited for dropshipping and wholesale sourcing workflows, while eBay is better for both buying and selling on a consumer marketplace.
WooCommerce is a better choice if you want to own and operate your own e-commerce store rather than listing on an existing marketplace.
Frequently asked questions
How do I connect Replit to the eBay API?
Register a free developer app at developer.ebay.com to get your App ID (Client ID) and Cert ID (Client Secret). Store them in Replit Secrets (lock icon π in sidebar). Use the Client Credentials OAuth flow to get an access token, then call the Browse API from your Node.js or Python server-side code.
Does Replit work with the eBay Browse API?
Yes. The eBay Browse API accepts standard HTTPS requests from any server, including Replit. The API does not require a static IP address, so Replit's dynamic outbound IPs work fine. All calls should be made from your server-side code, not from browser JavaScript.
How do I store my eBay API credentials in Replit?
Click the lock icon (π) in the Replit sidebar, then add EBAY_CLIENT_ID (App ID) and EBAY_CLIENT_SECRET (Cert ID) as secrets. Access them in Node.js as process.env.EBAY_CLIENT_ID or in Python as os.environ['EBAY_CLIENT_ID'].
Can I use the eBay API for free from Replit?
The eBay Developer Program is free to join and includes a daily call quota for API access. There are no per-call fees for the Browse API. Selling operations via the Sell API may have associated eBay seller fees for actual listings, but the API access itself is free.
Do I need a static IP to use the eBay API from Replit?
No. The eBay API does not require IP allowlisting for standard developer access. Replit's dynamic outbound IPs work without any special configuration on the eBay side.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation