To integrate eBay's REST APIs with Bolt.new, register an eBay developer app, generate OAuth tokens server-side using client credentials flow, and proxy all API calls through a Next.js API route that keeps your client secret out of browser code. Use the Browse API for searching and displaying listings, and the Sell API for managing inventory. OAuth token exchange must happen server-side — the WebContainer-safe pattern proxies everything through an API route before deployment.
Build eBay Listing Management Tools and Price Comparison Apps with Bolt.new
eBay's modern REST API suite communicates entirely over HTTPS with JSON payloads, making it architecturally compatible with Bolt.new's WebContainer runtime. Every product search, listing query, inventory update, and order operation travels over standard HTTP — no TCP sockets, no native binaries, no special runtimes. You can build price comparison tools, seller dashboards, order management interfaces, and competitor research apps, all runnable inside Bolt's preview during development.
eBay's API suite is divided into two main families: the Browse API for buyer-facing search and product discovery, and the Sell APIs for seller-facing inventory, listings, and order management. The Browse API uses application-only OAuth (client credentials grant), which requires only your app credentials and works without user interaction. The Sell APIs may additionally require user OAuth (authorization code grant) where a seller must log in and authorize your app — this OAuth flow requires a registered callback URL and needs a deployed app URL rather than Bolt's preview.
The most important security constraint for eBay in Bolt is that OAuth token exchange must happen server-side. The client credentials grant requires sending your `client_id:client_secret` encoded as Base64 Basic Auth — exposing the client secret in browser code would allow anyone to make API calls billed against your eBay developer account. Bolt's Next.js API route pattern solves this perfectly: your React components call your own `/api/ebay` route, which securely handles token acquisition and eBay API proxying on the server side.
Integration method
Bolt.new generates a Next.js API route that handles eBay's OAuth 2.0 client credentials grant server-side, exchanges tokens, and proxies all Browse and Sell API calls. Your eBay client secret never reaches the browser. Outbound HTTPS calls to eBay's APIs work in Bolt's WebContainer preview for search and listing display. Webhook-based notifications for order updates require a deployed URL on Netlify or Bolt Cloud.
Prerequisites
- A Bolt.new account with a Next.js project
- An eBay developer account (free at developer.ebay.com)
- An eBay developer application registered in the developer portal (provides client ID and client secret)
- Knowledge of whether you need Browse API only (application OAuth) or Sell API (user OAuth requiring deployment)
Step-by-step guide
Register an eBay Developer Application
Register an eBay Developer Application
The eBay developer program is free to join and gives you access to sandbox and production API credentials. Go to developer.ebay.com and sign in with your eBay account (or create one). Navigate to 'Get Started' and then 'Register for eBay Developer Program.' Once registered, go to the developer portal at developer.ebay.com/my/keys and create an application. Click 'Create a keyset' and give your application a descriptive name. eBay provides two sets of credentials: Sandbox (for testing with fake data) and Production (for real eBay data). Each set includes three values: App ID (this is the `client_id`), Cert ID (this is the `client_secret`), and Dev ID (a unique developer identifier you typically do not use directly in API calls). For initial development, use Sandbox credentials — eBay's sandbox environment has pre-populated test data that looks realistic. For the Sell API features, you will also need to configure an RuName (Redirect URL Name) in the developer portal under 'User Tokens.' The RuName is a registered alias for your OAuth callback URL. For development, eBay provides a default 'Accept URL' for the sandbox that you can use for testing. For production user OAuth, register your actual deployed URL. Write down your App ID (client_id), Cert ID (client_secret), and for user OAuth your RuName — you will need all three in your .env file.
Pro tip: Start with Sandbox credentials and test thoroughly before switching to Production. eBay's sandbox has test buyer/seller accounts and fake listings that let you test the full API flow without real money or inventory.
Expected result: You have eBay developer application credentials: App ID (client_id) and Cert ID (client_secret) for both Sandbox and Production environments, saved securely.
Implement OAuth Client Credentials Grant in a Next.js API Route
Implement OAuth Client Credentials Grant in a Next.js API Route
eBay's OAuth 2.0 implementation requires the client credentials grant for application-level access (Browse API) and the authorization code grant for user-level access (Sell API). The client credentials flow is simpler: you send your client_id and client_secret to eBay's token endpoint and receive an access token. This token expires (typically after 2 hours) and must be refreshed. Critically, this entire exchange must happen server-side — never in a React component or any client-side code. The token request uses HTTP Basic Auth with `client_id:client_secret` Base64-encoded, and a `grant_type=client_credentials` body. eBay's token endpoint for sandbox is `https://api.sandbox.ebay.com/identity/v1/oauth2/token` and for production is `https://api.ebay.com/identity/v1/oauth2/token`. The scope parameter specifies which APIs your token grants access to — for the Browse API, use `https://api.ebay.com/oauth/api_scope`. For production code, cache the token and reuse it until it expires rather than fetching a new one on every request. You can store the token in a module-level variable (server memory) or in a cache service. The token response includes `expires_in` (seconds) which tells you when to refresh. In Bolt's development environment with Next.js, a module-level cache works fine for testing. For production deployments on serverless platforms (Netlify Functions, Vercel Edge), be aware that each function invocation may be a fresh process, so module-level caching may not persist across requests — implement a proper cache service or accept the small overhead of re-fetching tokens.
Create a Next.js API route at app/api/ebay/route.ts that handles eBay Browse API calls. Implement OAuth client credentials token acquisition using EBAY_CLIENT_ID and EBAY_CLIENT_SECRET from process.env. Cache the token in module memory and refresh when expired. Support a 'search' action via query params that calls eBay's Browse API item search endpoint. Return formatted listing data with title, price, condition, and image URL. Use sandbox endpoints during development.
Paste this in Bolt.new chat
1// app/api/ebay/route.ts2import { NextResponse } from 'next/server';34const EBAY_CLIENT_ID = process.env.EBAY_CLIENT_ID;5const EBAY_CLIENT_SECRET = process.env.EBAY_CLIENT_SECRET;6const IS_SANDBOX = process.env.EBAY_SANDBOX === 'true';78const EBAY_API_BASE = IS_SANDBOX9 ? 'https://api.sandbox.ebay.com'10 : 'https://api.ebay.com';11const EBAY_TOKEN_URL = `${EBAY_API_BASE}/identity/v1/oauth2/token`;1213// Module-level token cache (works for dev; use Redis/KV for production serverless)14let cachedToken: { value: string; expiresAt: number } | null = null;1516async function getApplicationToken(): Promise<string> {17 if (cachedToken && cachedToken.expiresAt > Date.now() + 60_000) {18 return cachedToken.value;19 }2021 const credentials = Buffer.from(`${EBAY_CLIENT_ID}:${EBAY_CLIENT_SECRET}`).toString('base64');2223 const response = await fetch(EBAY_TOKEN_URL, {24 method: 'POST',25 headers: {26 'Authorization': `Basic ${credentials}`,27 'Content-Type': 'application/x-www-form-urlencoded',28 },29 body: 'grant_type=client_credentials&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope',30 });3132 if (!response.ok) {33 throw new Error(`eBay token request failed: ${response.statusText}`);34 }3536 const data = await response.json();37 cachedToken = {38 value: data.access_token,39 expiresAt: Date.now() + data.expires_in * 1000,40 };41 return cachedToken.value;42}4344export async function GET(request: Request) {45 const { searchParams } = new URL(request.url);46 const action = searchParams.get('action');4748 try {49 const token = await getApplicationToken();5051 if (action === 'search') {52 const query = searchParams.get('q') || '';53 const limit = searchParams.get('limit') || '20';54 const minPrice = searchParams.get('minPrice');55 const maxPrice = searchParams.get('maxPrice');56 const condition = searchParams.get('condition'); // NEW, USED, etc.5758 const filters: string[] = [];59 if (minPrice || maxPrice) {60 filters.push(`price:[${minPrice || '*'}..${maxPrice || '*'}],priceCurrency:USD`);61 }62 if (condition) filters.push(`conditions:{${condition}}`);6364 const params = new URLSearchParams({65 q: query,66 limit,67 ...(filters.length > 0 && { filter: filters.join(',') }),68 fieldgroups: 'EXTENDED',69 sort: 'price',70 });7172 const res = await fetch(73 `${EBAY_API_BASE}/buy/browse/v1/item_summary/search?${params}`,74 { headers: { 'Authorization': `Bearer ${token}`, 'X-EBAY-C-MARKETPLACE-ID': 'EBAY_US' } }75 );7677 const data = await res.json();78 return NextResponse.json(data);79 }8081 return NextResponse.json({ error: 'Unknown action' }, { status: 400 });82 } catch (err) {83 const message = err instanceof Error ? err.message : 'Unknown error';84 return NextResponse.json({ error: message }, { status: 500 });85 }86}Pro tip: Set EBAY_SANDBOX=true in .env during development to use eBay's sandbox environment with test data. Switch to false and use production credentials only when ready to go live.
Expected result: The API route acquires an eBay OAuth token and successfully returns search results. The token is cached so subsequent requests are fast.
Configure Environment Variables and Connect to Bolt
Configure Environment Variables and Connect to Bolt
Add your eBay credentials to the `.env` file in your Bolt project root. Server-side credentials in Next.js do not need a `NEXT_PUBLIC_` prefix — they are accessible only in API routes and server components, never in client-side JavaScript bundles. The three variables you need are `EBAY_CLIENT_ID` (your App ID from the developer portal), `EBAY_CLIENT_SECRET` (your Cert ID), and `EBAY_SANDBOX` set to `true` for development. Treat the Cert ID (client secret) as highly sensitive — anyone with your client secret can make API calls under your developer account and potentially access or modify eBay seller data your account has been authorized for. After saving the `.env` file, restart the Bolt development server to pick up the new values. In the Bolt terminal, press Ctrl+C to stop the current server and run `npm run dev` to restart. Your API route should now successfully acquire tokens from eBay's sandbox and execute search queries. Test the endpoint by navigating to `/api/ebay?action=search&q=laptop&limit=5` in the preview — you should see JSON results with eBay sandbox listings.
Add eBay environment variables to .env: EBAY_CLIENT_ID=your-app-id, EBAY_CLIENT_SECRET=your-cert-id, EBAY_SANDBOX=true. Show a test search for 'vintage camera' using the eBay API and display 6 results in product cards with image, title, price, and condition badge.
Paste this in Bolt.new chat
1# .env2EBAY_CLIENT_ID=your-ebay-app-id3EBAY_CLIENT_SECRET=your-ebay-cert-id4EBAY_SANDBOX=truePro tip: eBay sandbox App IDs look like 'YourName-AppName-SBX-xxxx' and production App IDs look like 'YourName-AppName-PRD-xxxx'. Confirm you are using the right environment by checking the -SBX- or -PRD- in the App ID.
Expected result: Environment variables are configured. The eBay API route returns sandbox search results when tested with a sample query.
Build the eBay Listings Display Component
Build the eBay Listings Display Component
With the API route working, build a React component that searches eBay and displays results in a data table or card grid. The component calls your `/api/ebay` route (not eBay directly) and renders the listing data with images, prices, conditions, and seller information. eBay's Browse API item_summary search returns items with a consistent schema: `itemId`, `title`, `price` (amount and currency), `condition`, `image` (imageUrl), `itemWebUrl`, `seller` (username and feedbackPercentage), and `shippingOptions`. Map these into your React component with appropriate styling. For condition display, eBay uses standardized condition strings: 'NEW', 'LIKE_NEW', 'EXCELLENT', 'VERY_GOOD', 'GOOD', 'ACCEPTABLE', 'FOR_PARTS_OR_NOT_WORKING'. Add visual badges with appropriate colors (green for NEW, yellow for GOOD, gray for PARTS). For price display, format the currency correctly using JavaScript's `Intl.NumberFormat` — eBay returns prices as strings like '29.99' with a separate currency code 'USD'. The Buy Browse API returns up to 10,000 items per search with pagination via `offset` and `limit` parameters. Implement 'Load More' pagination using the `total` count from the response and incrementing the `offset` parameter. Bolt's AI can generate this component in detail — provide the response schema in your prompt for best results.
Build an EbaySearchResults React component. It should call /api/ebay?action=search with query, condition, minPrice, maxPrice, and limit params. Display results in a responsive grid of product cards. Each card shows: product image, title (truncated to 2 lines), price formatted as USD, condition badge with color coding (green=NEW, yellow=USED, gray=FOR_PARTS), seller username and feedback percentage, and a 'View on eBay' link. Add a Load More button using offset pagination.
Paste this in Bolt.new chat
1// components/EbaySearchResults.tsx2import { useState } from 'react';34interface EbayItem {5 itemId: string;6 title: string;7 price: { value: string; currency: string };8 condition: string;9 image?: { imageUrl: string };10 itemWebUrl: string;11 seller: { username: string; feedbackPercentage: string };12}1314interface SearchFilters {15 query: string;16 condition?: string;17 minPrice?: string;18 maxPrice?: string;19}2021export function EbaySearchResults() {22 const [filters, setFilters] = useState<SearchFilters>({ query: '' });23 const [items, setItems] = useState<EbayItem[]>([]);24 const [total, setTotal] = useState(0);25 const [offset, setOffset] = useState(0);26 const [loading, setLoading] = useState(false);27 const LIMIT = 20;2829 const search = async (newOffset = 0) => {30 setLoading(true);31 const params = new URLSearchParams({32 action: 'search',33 q: filters.query,34 limit: String(LIMIT),35 offset: String(newOffset),36 ...(filters.condition && { condition: filters.condition }),37 ...(filters.minPrice && { minPrice: filters.minPrice }),38 ...(filters.maxPrice && { maxPrice: filters.maxPrice }),39 });40 const res = await fetch(`/api/ebay?${params}`);41 const data = await res.json();42 if (newOffset === 0) {43 setItems(data.itemSummaries || []);44 } else {45 setItems(prev => [...prev, ...(data.itemSummaries || [])]);46 }47 setTotal(data.total || 0);48 setOffset(newOffset + LIMIT);49 setLoading(false);50 };5152 const conditionColor = (c: string) => {53 if (c === 'NEW') return 'bg-green-100 text-green-800';54 if (c.includes('USED') || c.includes('LIKE_NEW') || c.includes('EXCELLENT')) return 'bg-yellow-100 text-yellow-800';55 return 'bg-gray-100 text-gray-800';56 };5758 const formatPrice = (price: EbayItem['price']) =>59 new Intl.NumberFormat('en-US', { style: 'currency', currency: price.currency }).format(60 parseFloat(price.value)61 );6263 return (64 <div className="p-4">65 <div className="flex gap-2 mb-4 flex-wrap">66 <input67 placeholder="Search eBay..."68 value={filters.query}69 onChange={e => setFilters(f => ({ ...f, query: e.target.value }))}70 onKeyDown={e => e.key === 'Enter' && search()}71 className="flex-1 min-w-48 border rounded px-3 py-2"72 />73 <select74 value={filters.condition || ''}75 onChange={e => setFilters(f => ({ ...f, condition: e.target.value || undefined }))}76 className="border rounded px-3 py-2"77 >78 <option value="">Any condition</option>79 <option value="NEW">New</option>80 <option value="USED">Used</option>81 </select>82 <button onClick={() => search()} className="bg-yellow-400 px-4 py-2 rounded font-medium">83 Search84 </button>85 </div>86 {total > 0 && <p className="text-sm text-gray-500 mb-3">{total.toLocaleString()} results</p>}87 <div className="grid grid-cols-2 md:grid-cols-4 gap-4">88 {items.map(item => (89 <div key={item.itemId} className="border rounded p-3">90 {item.image && (91 <img src={item.image.imageUrl} alt={item.title} className="w-full h-32 object-contain mb-2" />92 )}93 <p className="text-sm font-medium line-clamp-2 mb-1">{item.title}</p>94 <p className="text-lg font-bold text-green-700">{formatPrice(item.price)}</p>95 <span className={`text-xs px-2 py-0.5 rounded ${conditionColor(item.condition)}`}>96 {item.condition.replace(/_/g, ' ')}97 </span>98 <p className="text-xs text-gray-500 mt-1">{item.seller.username} ({item.seller.feedbackPercentage}%)</p>99 <a href={item.itemWebUrl} target="_blank" rel="noopener noreferrer"100 className="text-xs text-blue-600 underline mt-1 block">101 View on eBay102 </a>103 </div>104 ))}105 </div>106 {items.length < total && (107 <button onClick={() => search(offset)} disabled={loading}108 className="mt-4 w-full border rounded py-2 text-sm hover:bg-gray-50">109 {loading ? 'Loading...' : `Load more (${total - items.length} remaining)`}110 </button>111 )}112 </div>113 );114}Pro tip: eBay sandbox returns realistic-looking test data but the 'View on eBay' links point to sandbox item URLs that may not exist. Switch to production credentials before sharing the app with users.
Expected result: The search component displays eBay listings as a product card grid with images, prices, conditions, and seller info. Pagination loads additional results without reloading the page.
Deploy and Test in Production Environment
Deploy and Test in Production Environment
To switch from eBay sandbox to production and to enable any webhook-based order notifications, deploy your Bolt project to Netlify or Bolt Cloud. eBay's notification system (eBay Marketplace Account Deletion Notification and other event notifications) sends POST requests to a publicly accessible URL — these cannot reach Bolt's WebContainer during development since the preview URL is not a stable public endpoint. For production deployment: push your project to GitHub from Bolt's Git panel, then import the repository in Netlify. In Netlify's Site configuration > Environment variables, change `EBAY_CLIENT_ID` and `EBAY_CLIENT_SECRET` to your Production credentials (not sandbox), and set `EBAY_SANDBOX=false`. The build command for Next.js is `npm run build` and the output directory is `.next`. For user OAuth (Sell API): once deployed, go to your eBay developer application settings and update the Production RuName to point to your Netlify URL's OAuth callback path (e.g., `https://your-app.netlify.app/api/ebay/callback`). eBay's production API requires that the redirect URL for user authorization exactly matches a registered RuName — mismatches cause the OAuth flow to fail with an 'invalid redirect_uri' error.
Prepare the eBay integration for production deployment. Add an /api/ebay/health route that checks if the eBay credentials are configured and can acquire a token (without exposing the token in the response). Add proper error handling in the main API route for expired tokens (re-fetch rather than returning an error). Document in a code comment that EBAY_SANDBOX should be set to false and production credentials used when deploying to Netlify.
Paste this in Bolt.new chat
1// app/api/ebay/health/route.ts2import { NextResponse } from 'next/server';34export async function GET() {5 const clientId = process.env.EBAY_CLIENT_ID;6 const clientSecret = process.env.EBAY_CLIENT_SECRET;78 if (!clientId || !clientSecret) {9 return NextResponse.json(10 { status: 'error', message: 'eBay credentials not configured' },11 { status: 500 }12 );13 }1415 try {16 const isSandbox = process.env.EBAY_SANDBOX === 'true';17 const tokenUrl = isSandbox18 ? 'https://api.sandbox.ebay.com/identity/v1/oauth2/token'19 : 'https://api.ebay.com/identity/v1/oauth2/token';20 const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');21 const res = await fetch(tokenUrl, {22 method: 'POST',23 headers: { 'Authorization': `Basic ${credentials}`, 'Content-Type': 'application/x-www-form-urlencoded' },24 body: 'grant_type=client_credentials&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope',25 });26 if (!res.ok) throw new Error(`Token request failed: ${res.status}`);27 return NextResponse.json({28 status: 'ok',29 environment: isSandbox ? 'sandbox' : 'production',30 });31 } catch (err) {32 return NextResponse.json(33 { status: 'error', message: err instanceof Error ? err.message : 'Unknown error' },34 { status: 500 }35 );36 }37}Pro tip: Always test with eBay sandbox credentials first. Switching to production credentials with real eBay data should only happen after all functionality is verified in sandbox.
Expected result: The app is deployed to Netlify with production eBay credentials. The /api/ebay/health endpoint returns { status: 'ok', environment: 'production' } confirming proper configuration.
Common use cases
Product Price Comparison Tool
Build a price research tool that searches eBay for a product and displays listings sorted by price, condition, and seller rating. Useful for resellers and buyers comparing eBay prices against other platforms or their own inventory costs. Uses the Browse API's item search endpoint with filters for condition, price range, and location.
Build an eBay price comparison tool. Create a Next.js API route at /api/ebay/search that uses eBay's Browse API to search for items. Handle OAuth client credentials token acquisition server-side using EBAY_CLIENT_ID and EBAY_CLIENT_SECRET from process.env. Return listings with title, price, condition, seller feedback score, item URL, and main image. Build a React component with a search input, price range filter, condition dropdown, and results displayed in a sortable data table.
Copy this prompt to try it in Bolt.new
Seller Listing Management Dashboard
Create a dashboard for eBay sellers to view their active listings, monitor prices, check inventory quantities, and quickly update prices or end listings. Connects to the Sell API Inventory and Listing endpoints. Particularly useful for high-volume sellers managing dozens or hundreds of active listings who need faster workflows than eBay's native interface.
Build an eBay seller dashboard. Create Next.js API routes for: 1) GET /api/ebay/listings to fetch the authenticated seller's active listings using the Sell Inventory API, 2) PUT /api/ebay/listings/[listingId] to update a listing's price or quantity, 3) DELETE /api/ebay/listings/[listingId] to end a listing. Handle OAuth user token from a stored cookie. Display listings in a data grid with inline editing for price and quantity. Add a note that user OAuth requires the deployed app URL.
Copy this prompt to try it in Bolt.new
eBay Category Research and Analytics Widget
Build a category research tool that searches eBay for products in a specific category, aggregates pricing data (min, max, average, median), and shows the distribution of sold vs active listings. Helps sellers identify pricing opportunities and understand market depth before listing new products.
Build an eBay market research tool using the Browse API. Create an API route that searches for a product query within a specific category ID and returns aggregated stats: total results count, price range (min/max), average price, and the top 20 listings sorted by price. Use EBAY_CLIENT_ID and EBAY_CLIENT_SECRET for client credentials OAuth. Display results as a price histogram chart and a listings table.
Copy this prompt to try it in Bolt.new
Troubleshooting
OAuth token request returns 401 with 'Invalid client credentials'
Cause: The EBAY_CLIENT_ID or EBAY_CLIENT_SECRET is incorrect, or you are using Sandbox credentials against the production token endpoint (or vice versa).
Solution: Verify your App ID and Cert ID in the eBay developer portal at developer.ebay.com/my/keys. Sandbox IDs contain '-SBX-' and production IDs contain '-PRD-'. Ensure EBAY_SANDBOX in your .env matches the credentials you are using.
Browse API search returns 200 but 'itemSummaries' is undefined or missing from the response
Cause: The search query returned zero results (common in sandbox with unusual queries), or the response schema has changed. The eBay Browse API returns 'itemSummaries' only when there are results — it omits the field entirely for empty result sets.
Solution: Default to an empty array when accessing itemSummaries: const items = data.itemSummaries || []. In sandbox, try common search terms like 'laptop', 'phone', or 'watch' which have pre-populated test data.
1const data = await res.json();2const items: EbayItem[] = data.itemSummaries ?? [];3const total: number = data.total ?? 0;API calls succeed in Bolt's preview but fail after deploying to Netlify with CORS errors
Cause: The client-side React component is calling the eBay API directly instead of going through the /api/ebay Next.js route, or the API route URL is hardcoded to localhost.
Solution: Verify all eBay API calls in your React components use relative URLs like /api/ebay (not https://api.ebay.com or http://localhost:3000/api/ebay). Relative URLs work correctly in both development and production without any changes.
1// Correct: relative URL works in both dev and production2const res = await fetch('/api/ebay?action=search&q=' + query);34// Incorrect: hardcoded localhost breaks in production5const res = await fetch('http://localhost:3000/api/ebay?action=search&q=' + query);eBay webhook notifications are not arriving — order events happen on eBay but nothing reaches the app
Cause: The webhook endpoint URL is the Bolt WebContainer preview URL, which is not publicly accessible. WebContainers cannot receive incoming HTTP connections.
Solution: Deploy the app to Netlify or Bolt Cloud first, then register the deployed URL as the notification endpoint in your eBay developer account under Application Settings > Notifications. The webhook URL must be a stable, publicly accessible HTTPS endpoint.
Best practices
- Cache eBay OAuth tokens in server memory for their full 2-hour lifetime rather than fetching a new token on every request — token requests count against rate limits and add latency to every API call.
- Never expose EBAY_CLIENT_SECRET in any client-side code, environment variable with NEXT_PUBLIC_ prefix, or commit it to a public GitHub repository — treat it with the same sensitivity as a database password.
- Use eBay's sandbox environment throughout development and only switch to production credentials on your deployed site — this prevents accidentally listing real items or modifying production data during development.
- Implement response caching for Browse API search results since product listings change slowly — cache results for 5-15 minutes to stay well within eBay's API rate limits and improve response times.
- Request only the Browse API fields you render using the 'fieldgroups' parameter; 'COMPACT' returns basic listing data while 'EXTENDED' adds shipping, returns, and seller details — choose based on what your UI displays.
- Handle eBay's pagination correctly using the 'offset' parameter rather than loading all results at once — searches can return millions of items and fetching them all would exhaust your rate limit immediately.
- Validate that your app handles the 'condition' field gracefully since eBay returns both standardized condition IDs and human-readable labels, and the format can differ between sandbox and production.
Alternatives
AliExpress API is better suited for dropshipping product sourcing with lower-priced wholesale items, while eBay is stronger for resale, auctions, and used goods.
Etsy's API targets handmade and vintage marketplaces with simpler OAuth flows, making it easier to integrate for craft-focused e-commerce platforms.
WooCommerce is a self-hosted store platform rather than a marketplace — use it to build your own storefront rather than interfacing with eBay's marketplace.
Printful is a print-on-demand fulfillment service that can be combined with eBay for automated product creation and order fulfillment.
Frequently asked questions
Does Bolt.new have a native eBay integration?
No — Bolt.new does not have a built-in eBay connector. You build the integration manually using a Next.js API route as a server-side proxy that handles OAuth and API calls. Bolt's AI assistant generates all the boilerplate code from a single prompt, so setup is fast even without a native integration.
Can I use the eBay API during development in Bolt's preview without deploying?
Yes — the Browse API for searching and viewing eBay listings works fully in Bolt's WebContainer preview. Your Next.js API route makes outbound HTTPS calls to eBay's sandbox, which the WebContainer handles correctly. The only features requiring deployment are webhook notifications (incoming HTTP requests) and user OAuth flows where eBay needs to redirect to a stable callback URL.
What is the difference between eBay's client_id (App ID) and client_secret (Cert ID)?
eBay uses Atlassian-style naming in its developer portal. The 'App ID' is what most OAuth implementations call client_id — it identifies your application publicly. The 'Cert ID' is what most OAuth implementations call client_secret — it authenticates your app server-side and must never be exposed in client code. The 'Dev ID' is a unique identifier for your developer account that you typically do not use in API calls directly.
How do I switch from eBay sandbox to production in my Bolt app?
In your .env file, change EBAY_CLIENT_ID to your Production App ID (contains -PRD-), EBAY_CLIENT_SECRET to your Production Cert ID, and set EBAY_SANDBOX=false. The API URLs switch automatically if your code uses the IS_SANDBOX conditional. For Netlify deployment, update the same environment variables in Netlify's Site configuration. Always test thoroughly in sandbox before making this switch.
What are eBay's API rate limits?
eBay's Browse API allows 5,000 calls per day for new applications on the default tier. The Sell APIs have different limits depending on the seller's account level. Rate limit headers in the response (X-EBAY-C-REQUEST-LIMIT-REMAINING) show remaining quota. For higher limits, apply for increased access through the eBay developer portal. Implement caching to stay well within limits.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation