Skip to main content
RapidDev - Software Development Agency
v0-integrationsNext.js API Route

How to Integrate Etsy API with V0

To integrate the Etsy API with V0 by Vercel, generate your shop listings UI in V0, create a Next.js API route that authenticates with the Etsy OAuth2 flow and fetches listings using your API key, add your Etsy credentials as Vercel environment variables, and deploy. Your handmade marketplace storefront will display live product data from your Etsy shop.

What you'll learn

  • How to set up Etsy OAuth2 credentials and API key in the Etsy Developer Portal
  • How to create a Next.js API route that fetches shop listings from the Etsy Open API v3
  • How to store Etsy credentials securely as Vercel environment variables
  • How to display live Etsy listing data (images, prices, titles) in a V0-generated storefront UI
  • How to handle Etsy API pagination and rate limits in your integration
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate15 min read45 minutesE-commerceMarch 2026RapidDev Engineering Team
TL;DR

To integrate the Etsy API with V0 by Vercel, generate your shop listings UI in V0, create a Next.js API route that authenticates with the Etsy OAuth2 flow and fetches listings using your API key, add your Etsy credentials as Vercel environment variables, and deploy. Your handmade marketplace storefront will display live product data from your Etsy shop.

Display Your Etsy Shop Listings in a Custom Storefront

Etsy's marketplace has over 96 million active buyers, but its default shop interface offers limited customization. By connecting the Etsy Open API v3 to a V0-generated Next.js storefront, you can build a fully branded product display page, a custom portfolio site, or a headless shopping experience that reflects your brand identity rather than Etsy's generic template.

The integration works by having V0 generate a polished React UI for your product listings — cards with images, prices, and call-to-action buttons — while a Next.js API route handles the secure OAuth2 authentication and data fetching from Etsy's servers. Your API key and access token never touch the browser, so your Etsy credentials remain protected even in production.

This is particularly valuable for Etsy sellers who want to use their custom domain, embed their shop listings on a portfolio or blog, or build a multi-platform storefront that pulls products from both Etsy and other sources. The Etsy API returns rich data including listing photos, prices, quantities, tags, and shipping profiles — giving you everything you need to build a compelling shopping experience.

Integration method

Next.js API Route

The Etsy Open API v3 uses OAuth2 for authentication and requires server-side requests with your API key and access tokens. V0 generates the React storefront UI, and a Next.js API route in your app proxies all Etsy API calls securely — keeping your credentials server-side while fetching live listing data, images, prices, and inventory from your shop.

Prerequisites

  • A V0 account at v0.dev and a Vercel account for deployment
  • An Etsy seller account with an active shop (required to access the Etsy API)
  • An Etsy Developer account — register your app at developers.etsy.com to get an API key
  • Your Etsy shop's Shop ID (found in your Etsy shop URL or the Developer Portal after creating an app)
  • Basic familiarity with copying and pasting code and setting environment variables in the Vercel Dashboard

Step-by-step guide

1

Generate Your Etsy Shop Listings UI in V0

Start by using V0's chat interface to generate the React component that will display your Etsy listings. This is the UI layer — you're describing the visual design and layout you want, and V0 will produce a complete Next.js component with Tailwind CSS styling. Be specific about how you want each product card to look: image size, price formatting, the 'Buy on Etsy' button style, hover effects, and the overall grid layout. Describe your brand aesthetic — whether it's warm and artisanal, minimal and modern, or bold and colorful — so V0 produces styling that matches your identity. At this stage, V0 will generate the component with placeholder or mock data. That's expected — you'll connect it to the real Etsy API in the next steps. Focus on getting the layout and visual design right first. You can use the V0 Design Mode (Option+D) to tweak colors, spacing, and typography without spending generation credits. Once you're happy with the design, click 'Publish to Production' in V0 to get a live Vercel URL, and make note of the project — you'll be adding code to it in the following steps.

V0 Prompt

Create a shop listings page that fetches product data from /api/etsy/listings. Display each listing as a card with a square product photo, listing title in bold, price formatted as '$XX.XX', quantity available shown as a small badge, and a 'Buy on Etsy' button in terracotta/orange. Use a responsive grid: 1 column on mobile, 2 on tablet, 3 on desktop. Add a loading skeleton state and an error message state. Include a page header with 'My Shop' as the title.

Paste this in V0 chat

Pro tip: Ask V0 to include both a loading skeleton state and an error state in the component. This makes your UI feel professional and handles the inevitable cases where the Etsy API is slow or temporarily unavailable.

Expected result: V0 generates a complete React listings page with product cards, loading states, and error handling, deployed to a live Vercel URL with placeholder data.

2

Register Your App in the Etsy Developer Portal

Before writing any code, you need to register your application in the Etsy Developer Portal to obtain your API credentials. Navigate to developers.etsy.com and sign in with your Etsy account. Click 'Create a New App' and fill in the application details: give it a name like 'My Shop Storefront', select the appropriate app type (website), and provide your Vercel deployment URL as the callback URL. The callback URL format should be https://your-app.vercel.app/api/etsy/callback — you'll need the exact URL from your Vercel project dashboard. After creating the app, Etsy will display your API Key (also called the keystring) and your Shared Secret. Copy both of these immediately and store them in a secure password manager — you'll need them as environment variables. Also note that the Etsy API v3 uses OAuth 2.0 with PKCE for user-level access (to read orders and private shop data) but supports simple API key authentication for reading public listing data. For a public storefront displaying your own shop's public listings, you may only need the API key and your shop name. Keep your Shared Secret confidential — it should never appear in client-side code.

Pro tip: For displaying public listing data from your own shop, you only need the API key (keystring) — the full OAuth2 flow is required only for accessing private data like orders. Start with the simpler API key approach first.

Expected result: You have an Etsy API key (keystring) and shared secret saved securely, and your app is registered in the Etsy Developer Portal with your Vercel callback URL.

3

Create the Etsy API Route in Next.js

Now create the server-side API route that will proxy requests to the Etsy API. This route runs on Vercel's serverless infrastructure, meaning your Etsy API key stays completely server-side and is never exposed to the browser. In your V0 project, open the Code editor (Dev Mode or export to GitHub and edit locally) and create a new file at app/api/etsy/listings/route.ts. The route fetches your shop's active listings from the Etsy Open API v3 endpoint. The base URL is https://openapi.etsy.com/v3/application/ and every request must include your API key in the x-api-key header. The listings endpoint is /shops/{shop_id}/listings/active and supports pagination via limit and offset query parameters. The response includes listing_id, title, description, price (amount and currency_code), quantity, state, and url — plus an images array that you'll need to fetch separately via /listings/{listing_id}/images. For a performant storefront, consider fetching listings and their first image in parallel using Promise.all, or fetching listing images on-demand rather than upfront. Add error handling for the case where the Etsy API returns a 429 rate limit response — the API allows 10 requests per second by default.

app/api/etsy/listings/route.ts
1// app/api/etsy/listings/route.ts
2import { NextResponse } from 'next/server';
3
4const ETSY_API_BASE = 'https://openapi.etsy.com/v3/application';
5
6export async function GET(request: Request) {
7 const { searchParams } = new URL(request.url);
8 const limit = searchParams.get('limit') || '12';
9 const offset = searchParams.get('offset') || '0';
10
11 const shopId = process.env.ETSY_SHOP_ID;
12 const apiKey = process.env.ETSY_API_KEY;
13
14 if (!shopId || !apiKey) {
15 return NextResponse.json(
16 { error: 'Etsy credentials not configured' },
17 { status: 500 }
18 );
19 }
20
21 try {
22 // Fetch active listings
23 const listingsRes = await fetch(
24 `${ETSY_API_BASE}/shops/${shopId}/listings/active?limit=${limit}&offset=${offset}&includes=Images`,
25 {
26 headers: {
27 'x-api-key': apiKey,
28 },
29 next: { revalidate: 300 }, // Cache for 5 minutes
30 }
31 );
32
33 if (!listingsRes.ok) {
34 const errorText = await listingsRes.text();
35 console.error('Etsy API error:', listingsRes.status, errorText);
36 return NextResponse.json(
37 { error: `Etsy API returned ${listingsRes.status}` },
38 { status: listingsRes.status }
39 );
40 }
41
42 const data = await listingsRes.json();
43
44 // Transform to a clean response shape
45 const listings = data.results.map((listing: any) => ({
46 id: listing.listing_id,
47 title: listing.title,
48 price: {
49 amount: listing.price.amount / listing.price.divisor,
50 currency: listing.price.currency_code,
51 },
52 quantity: listing.quantity,
53 url: listing.url,
54 image: listing.images?.[0]?.url_570xN || listing.images?.[0]?.url_fullxfull || null,
55 }));
56
57 return NextResponse.json({
58 listings,
59 count: data.count,
60 total: data.count,
61 });
62 } catch (error) {
63 console.error('Failed to fetch Etsy listings:', error);
64 return NextResponse.json(
65 { error: 'Failed to fetch listings' },
66 { status: 500 }
67 );
68 }
69}

Pro tip: The ?includes=Images parameter in the Etsy API request fetches listing images in the same call, avoiding a second round-trip to fetch images separately. This significantly reduces latency on your storefront.

Expected result: Visiting /api/etsy/listings in your browser (after adding env vars) returns a JSON array of your Etsy shop listings with titles, prices, quantities, and image URLs.

4

Add Etsy Credentials to Vercel Environment Variables

Your API route reads credentials from environment variables — now you need to add those variables to your Vercel project so they're available at runtime. Open the Vercel Dashboard at vercel.com, navigate to your project, and click Settings → Environment Variables. You'll add three variables: ETSY_API_KEY (your API key / keystring from the Etsy Developer Portal), ETSY_SHOP_ID (your numeric shop ID — you can find this by calling https://openapi.etsy.com/v3/application/shops?shop_name=YOUR_SHOP_NAME with your API key, or by looking at your shop's URL in the Etsy admin), and ETSY_SHARED_SECRET (your OAuth shared secret, for future OAuth flows). For each variable, set the Environment to Production and Preview so your deployed app and Vercel preview deployments both have access. Click Save after each variable. After adding all variables, you must trigger a new deployment for the variables to take effect — Vercel bakes environment variables into deployments at build time for production. The simplest way is to push a small commit or click Redeploy in the Vercel Dashboard. Once redeployed, your API route at /api/etsy/listings will authenticate with Etsy and return your real listing data.

Pro tip: To find your numeric Etsy Shop ID, make a test request from your browser's address bar: https://openapi.etsy.com/v3/application/shops?shop_name=YOUR_SHOP_NAME — replace YOUR_SHOP_NAME with your Etsy shop name (no spaces, as it appears in your Etsy URL). The response JSON will include your shop_id.

Expected result: Three environment variables (ETSY_API_KEY, ETSY_SHOP_ID, ETSY_SHARED_SECRET) are set in the Vercel Dashboard and a fresh deployment is running with the new credentials.

5

Connect the UI Component to the Etsy API Route

Now connect your V0-generated UI to the real Etsy data by updating the component to fetch from your /api/etsy/listings endpoint. Use V0's chat to update the component, or edit the code directly in V0's code editor. The component should call the endpoint on mount using useEffect and useState (for a client component) or use Next.js Server Components with a direct fetch call (simpler and faster). The server-side approach is recommended for a listings page because it avoids a loading flash — the HTML arrives pre-populated with product data. In the V0 chat, describe that you want the listings page to be a React Server Component that fetches data from /api/etsy/listings at render time. V0 will generate an async server component with a fetch call and error boundary. Update the data mapping to use the fields from your API response shape: listing.id, listing.title, listing.price.amount, listing.price.currency, listing.quantity, listing.url, and listing.image. The 'Buy on Etsy' button should link to listing.url — this brings the customer directly to your Etsy listing for checkout, since Etsy handles all payment processing. For complex integration requirements, RapidDev's team can help you configure the full OAuth2 flow for accessing private order data or building a checkout redirect system.

V0 Prompt

Update the shop listings page to be a React Server Component that fetches data from /api/etsy/listings?limit=12 at render time using async/await. Map the response to display each listing.title, listing.price.amount formatted as currency, listing.quantity, and listing.image as the card photo. The 'Buy on Etsy' button should use listing.url as the href and open in a new tab. Wrap the fetch in a try/catch and show a user-friendly error message if the API fails.

Paste this in V0 chat

Pro tip: Set next: { revalidate: 300 } in your fetch call to enable Incremental Static Regeneration — your listings page will be cached and served as static HTML, regenerating every 5 minutes to pick up new Etsy listings or price changes.

Expected result: Your deployed storefront displays real product photos, titles, and prices from your live Etsy shop, with each 'Buy on Etsy' button linking to the correct Etsy listing page.

Common use cases

Branded Etsy Storefront on Custom Domain

Build a fully branded product gallery that displays your Etsy shop listings on your own domain. Customers browse your products with your visual identity, then click through to Etsy for checkout. This is ideal for artisans who want a professional web presence beyond the standard Etsy shop page.

V0 Prompt

Create a product gallery page that displays handmade jewelry listings from an API at /api/etsy/listings. Each product card should show a large photo, title, price in USD, quantity available, and a 'Buy on Etsy' button that links to the product. Use a responsive 3-column grid with Tailwind CSS and a warm, artisan aesthetic.

Copy this prompt to try it in V0

Portfolio Site with Live Shop Integration

An artist or craftsperson's portfolio site that showcases their work alongside a live shop section. The portfolio highlights their process and story, while a dedicated shop section fetches current listings from their Etsy store so inventory stays automatically up to date.

V0 Prompt

Build a portfolio homepage for a ceramic artist with a hero section, an 'About the Artist' section, and a 'Shop' section that loads products from /api/etsy/listings. The shop should display up to 6 featured listings in a masonry grid with hover effects showing price and title overlaid on the photo.

Copy this prompt to try it in V0

Etsy Shop Analytics Dashboard

An internal dashboard for Etsy sellers to monitor their shop's performance — listing views, favorites, active versus inactive items, and inventory levels — all in one place. The dashboard fetches data from multiple Etsy API endpoints and presents it with charts and sortable tables.

V0 Prompt

Create an analytics dashboard for an Etsy shop with a summary row showing total active listings, total favorites, and total views fetched from /api/etsy/shop-stats. Below, show a sortable table of all listings with columns for title, price, quantity, views, and favorites. Include a filter to show only active or sold-out items.

Copy this prompt to try it in V0

Troubleshooting

API route returns 401 Unauthorized or 'Invalid API key' error

Cause: The ETSY_API_KEY environment variable is missing, set incorrectly, or the variable name doesn't match exactly what the code references. Etsy returns 401 when the x-api-key header is absent or contains an invalid value.

Solution: Verify the variable name in your Vercel Dashboard is exactly ETSY_API_KEY (all caps, underscore). Copy the API key directly from the Etsy Developer Portal app page — it's the long alphanumeric string labeled 'Keystring'. Trigger a new deployment after any environment variable change for it to take effect.

API route returns an empty listings array even though you have active Etsy listings

Cause: The ETSY_SHOP_ID is incorrect or set to your shop name string instead of the numeric shop ID. The Etsy API v3 requires the numeric ID, not the shop name slug.

Solution: Fetch your numeric shop ID by calling: fetch('https://openapi.etsy.com/v3/application/shops?shop_name=YOUR_SHOP_NAME', { headers: { 'x-api-key': 'YOUR_KEY' } }). Look for shop_id in the response. Update the ETSY_SHOP_ID environment variable to this numeric value.

typescript
1// Temporary debug route to find your shop ID
2// app/api/etsy/find-shop/route.ts
3export async function GET() {
4 const res = await fetch(
5 `https://openapi.etsy.com/v3/application/shops?shop_name=${process.env.ETSY_SHOP_NAME}`,
6 { headers: { 'x-api-key': process.env.ETSY_API_KEY! } }
7 );
8 const data = await res.json();
9 return Response.json({ shop_id: data.results?.[0]?.shop_id });
10}

Listing images are null or broken — photos don't display

Cause: The Etsy API does not include images by default when fetching listings. Images must be explicitly requested using the ?includes=Images query parameter, or fetched in a separate request to /listings/{listing_id}/images.

Solution: Add ?includes=Images to the listings endpoint URL in your API route. If images are still missing, some listings may have no photos — add a fallback image in your component for listings where image is null.

typescript
1// Add includes=Images to your fetch URL
2const listingsRes = await fetch(
3 `${ETSY_API_BASE}/shops/${shopId}/listings/active?limit=${limit}&offset=${offset}&includes=Images`,
4 { headers: { 'x-api-key': apiKey } }
5);

Rate limit errors (429 Too Many Requests) after many page loads

Cause: The Etsy API allows 10 requests per second per API key by default. If multiple users load your storefront simultaneously or you're fetching many pages of listings, you'll hit this limit quickly.

Solution: Add Next.js caching to your fetch call with next: { revalidate: 300 } to cache responses for 5 minutes. This means Vercel serves cached listing data for most requests rather than calling the Etsy API on every page load. For high-traffic stores, increase the revalidate time or implement a Redis cache layer.

typescript
1const listingsRes = await fetch(
2 `${ETSY_API_BASE}/shops/${shopId}/listings/active?limit=${limit}`,
3 {
4 headers: { 'x-api-key': apiKey! },
5 next: { revalidate: 300 }, // Cache for 5 minutes
6 }
7);

Best practices

  • Always fetch Etsy API data through a Next.js API route — never call the Etsy API directly from client-side React components, as this would expose your API key in the browser's network tab.
  • Use Next.js Incremental Static Regeneration (next: { revalidate: 300 }) on your listings fetch to cache results and reduce API calls — Etsy listing data rarely changes by the minute.
  • Include error boundaries and loading states in your listings component so users see a graceful fallback rather than a blank page if the Etsy API is temporarily unavailable.
  • Store ETSY_API_KEY, ETSY_SHOP_ID, and ETSY_SHARED_SECRET as separate Vercel environment variables — never hardcode them in your source code or commit them to GitHub.
  • Always link customers to the Etsy listing URL for checkout rather than attempting to build your own checkout flow — Etsy's seller agreement requires transactions to occur on Etsy.
  • Request only the data fields you need. Use the ?fields parameter in Etsy API requests to limit the response payload size: ?fields=listing_id,title,price,quantity,url,images
  • Test your integration with a small limit parameter first (?limit=3) to verify the API connection works before loading your full catalog.
  • Handle the case where a listing's quantity reaches 0 — show an 'Out of Stock' badge or hide the listing rather than showing a 'Buy on Etsy' button for unavailable items.

Alternatives

Frequently asked questions

Do I need a paid Etsy account to use the Etsy API?

You need an Etsy seller account to access the Etsy API, but you don't need a paid plan specifically for API access. Creating a developer app at developers.etsy.com is free. However, Etsy charges standard listing fees and transaction fees when customers purchase through your Etsy listings, regardless of whether traffic comes from your custom storefront.

Can I use V0 and the Etsy API to build my own checkout that bypasses Etsy?

No — Etsy's seller agreement requires that all transactions happen on Etsy.com. The standard integration pattern is to display listings on your custom storefront and link customers to the Etsy listing URL for checkout. Attempting to replicate Etsy's checkout flow outside of Etsy would violate their terms of service and risk account suspension.

How do I display Etsy listing photos in my V0 Next.js app?

Fetch listings with the ?includes=Images parameter to get image URLs in the same API response. The Etsy API returns multiple image sizes — use url_570xN for standard product cards (a square 570px version) or url_fullxfull for larger displays. Add these Etsy image domains to your next.config.js images.remotePatterns configuration so Next.js Image optimization works correctly.

Why do my Etsy listings show outdated prices or sold-out items?

Caching is likely set too aggressively. By default, Next.js caches fetch responses indefinitely in production. Use next: { revalidate: 300 } to refresh every 5 minutes, or next: { revalidate: 60 } for more frequent updates. You can also add a revalidate API route that triggers on-demand regeneration when you update your Etsy shop.

Can I show Etsy reviews and ratings on my custom storefront?

Yes — the Etsy API v3 provides a /shops/{shop_id}/reviews endpoint that returns shop reviews with ratings, content, and reviewer information. You can fetch these through a separate API route at /api/etsy/reviews and display them as a testimonials section in your V0 UI. Reviews are public data and only require your API key, no OAuth flow needed.

How do I handle Etsy's OAuth2 flow if I need access to private data like orders?

For private data (orders, transactions, financial data), you need the full OAuth2 PKCE flow. Create a route at /api/etsy/auth that redirects to Etsy's authorization URL with your client_id and code_challenge, then a callback route at /api/etsy/callback that exchanges the authorization code for an access token. Store the access token and refresh token in your database (Neon or Supabase work well) and include the token as a Bearer token in subsequent API requests.

Will my Etsy storefront still work if I change my Etsy shop name?

If you're using the numeric ETSY_SHOP_ID (recommended), changing your Etsy shop name won't break your integration — the numeric ID stays constant. If you're using the shop name string in your API calls, you would need to update the ETSY_SHOP_ID environment variable in Vercel and redeploy after renaming your shop.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.