Connect FlutterFlow to the Etsy Open API v3 via OAuth 2.0 PKCE, with a Firebase Cloud Function handling the code-to-token exchange and refresh. Every FlutterFlow API Call to Etsy requires two headers simultaneously: Authorization: Bearer [token] AND x-api-key: [keystring]. Missing either header returns 401 even with a valid token. Build a seller dashboard to display active listings and track orders.
| Fact | Value |
|---|---|
| Tool | Etsy API |
| Category | E-commerce |
| Method | FlutterFlow API Call |
| Difficulty | Advanced |
| Time required | 90 minutes |
| Last updated | July 2026 |
Build an Etsy Seller Dashboard in FlutterFlow
Etsy's Open API v3 (base URL https://openapi.etsy.com/v3) is the official way to access Etsy shop data — listings, orders, receipts, and transactions — on behalf of an individual seller. The most common FlutterFlow use case is a seller dashboard app: a custom mobile interface where an Etsy seller can view their active listings, track incoming orders, and monitor shop performance without switching between the Etsy mobile app and their notes.
Etsy's authentication combines two separate mechanisms that both appear on every API call. First, OAuth 2.0 PKCE provides per-seller authorization — the seller logs in through Etsy's consent screen, grants your app permission to their shop data, and your app receives an access token. Second, an x-api-key header carries your application's keystring on every single request, independent of the OAuth token. This double-header requirement is unique to Etsy v3 and is the #1 source of 401 errors for developers new to this API: adding only the Bearer token (forgetting the x-api-key) or adding only the x-api-key (without the Bearer) both return 401 with no clear error message.
The PKCE OAuth flow requires generating a code_verifier and code_challenge, redirecting the user to Etsy's consent page, capturing the returned authorization code, and exchanging it for an access token. This exchange must happen server-side — doing it in raw Flutter client code would expose the code_verifier to manipulation and makes refresh token storage insecure. A Firebase Cloud Function is the right home for this logic. Etsy's API is free for developers (register at developers.etsy.com); commercial use with higher rate limits requires approval. The typical rate limit is 10 QPS and 10,000 requests per day per app — verify current limits in Etsy's developer documentation, as they change based on your application's approval status.
Integration method
FlutterFlow connects to Etsy Open API v3 using a two-header setup: a Bearer access token (obtained via PKCE OAuth through a Firebase Cloud Function) and an x-api-key keystring on every request. The Cloud Function handles the OAuth authorization code exchange and refresh token management, returning only the short-lived Bearer to FlutterFlow. Etsy listing and order data is then fetched directly via FlutterFlow API Calls using both headers.
Prerequisites
- An Etsy developer account at developers.etsy.com with an app registered and a keystring issued
- Your Etsy app's keystring (this is the x-api-key value — distinct from the OAuth client_id which is the same value in Etsy v3)
- A Firebase project on the Blaze plan with Cloud Functions enabled — required for the PKCE token exchange and outbound HTTP calls
- Firebase Authentication enabled in your Firebase project (for per-user token storage in Firestore)
- A FlutterFlow project with Firebase connected via Settings & Integrations → Firebase
Step-by-step guide
Register your Etsy app and obtain a keystring
Navigate to developers.etsy.com and sign in with your Etsy account. Click Create a New App. Fill in the application name, website, and a brief description of what your FlutterFlow app will do. Under the redirect URI, enter a URI that your Cloud Function can accept — for the PKCE server-side exchange flow, you can use a Cloud Function URL that will receive the authorization code after the user consents. A common approach is to use https://us-central1-YOUR_PROJECT.cloudfunctions.net/etsyOauthCallback as the redirect URI. After creating the app, Etsy provides two values: a Keystring (also called the API key) and a Shared Secret. In Etsy Open API v3, the keystring serves double duty: it is both the x-api-key header value on every API call AND the OAuth client_id in the PKCE flow. The Shared Secret is less commonly needed for PKCE guest flows but store it securely in Firebase Functions environment variables alongside the keystring. Select the OAuth scopes your app needs. For a listing and order dashboard, you'll need at minimum: listings_r (read listings), transactions_r (read orders/receipts), shops_r (read shop info). Grant only the scopes your app actually uses — requesting unnecessary scopes reduces the chance Etsy approves your app for commercial use. Note: new Etsy developer apps start with standard rate limits (typically 10 QPS / 10,000 requests per day — verify in the current developer docs). If you plan to build a multi-seller platform or a high-volume app, apply for commercial API access through Etsy's developer program.
Pro tip: In Etsy Open API v3, your keystring and your OAuth client_id are the SAME value. When you see examples that show client_id in the OAuth URL, that's your keystring. This confuses many developers who expect a separate OAuth client ID.
Expected result: Your Etsy app is created with a keystring, your redirect URI is registered, and your required OAuth scopes are selected.
Deploy a Firebase Cloud Function for Etsy OAuth PKCE
The Etsy OAuth 2.0 PKCE flow requires generating a cryptographically random code_verifier, hashing it to a code_challenge, constructing the authorization URL with both values, redirecting the user to Etsy's consent screen, and then exchanging the returned authorization code for access and refresh tokens. This cannot be done safely in raw Dart client code — the code_verifier would be accessible in the app binary, and storing the refresh token in App State would lose it every time the app restarts. Deploy two Firebase Cloud Functions: one that generates a PKCE authorization URL and temporary state (/etsyAuthUrl), and one that receives the Etsy OAuth callback, performs the token exchange, and stores the refresh token securely in Firestore per user (/etsyOauthCallback). Store your Etsy keystring in Firebase Functions environment variables as ETSY_KEYSTRING and your registered redirect URI as ETSY_REDIRECT_URI. The token exchange function stores the refresh token in Firestore at users/{userId}/etsyTokens/{shopId} — this means each user of your FlutterFlow app can authorize multiple Etsy shops independently. The function returns only the short-lived access token and the token's expiry time back to FlutterFlow. FlutterFlow never sees the refresh token — only the Cloud Function reads and stores it. For the authorization URL endpoint, FlutterFlow calls /etsyAuthUrl with the user's Firebase UID, and the function generates a PKCE pair, stores the code_verifier temporarily in Firestore (for the callback to retrieve), and returns the full Etsy authorization URL including the code_challenge. FlutterFlow then launches this URL in an in-app browser or WebView.
1const functions = require('firebase-functions');2const axios = require('axios');3const crypto = require('crypto');4const admin = require('firebase-admin');56if (!admin.apps.length) admin.initializeApp();7const db = admin.firestore();89const KEYSTRING = process.env.ETSY_KEYSTRING;10const REDIRECT_URI = process.env.ETSY_REDIRECT_URI;11const TOKEN_URL = 'https://api.etsy.com/v3/public/oauth/token';1213function generatePKCE() {14 const verifier = crypto.randomBytes(32).toString('base64url');15 const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');16 return { verifier, challenge };17}1819// Step 1: Generate the Etsy authorization URL20exports.etsyAuthUrl = functions.https.onRequest(async (req, res) => {21 res.set('Access-Control-Allow-Origin', '*');22 if (req.method === 'OPTIONS') { res.status(204).send(''); return; }2324 const userId = req.query.userId;25 if (!userId) { res.status(400).json({ error: 'userId required' }); return; }2627 const { verifier, challenge } = generatePKCE();28 const state = crypto.randomBytes(16).toString('hex');2930 // Store verifier and state temporarily (expires in 10 min)31 await db.collection('etsyPkceState').doc(state).set({32 verifier, userId,33 createdAt: admin.firestore.FieldValue.serverTimestamp(),34 });3536 const scopes = 'listings_r transactions_r shops_r';37 const authUrl = `https://www.etsy.com/oauth/connect?response_type=code` +38 `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +39 `&scope=${encodeURIComponent(scopes)}` +40 `&client_id=${KEYSTRING}` +41 `&state=${state}` +42 `&code_challenge=${challenge}` +43 `&code_challenge_method=S256`;4445 res.status(200).json({ authUrl });46});4748// Step 2: Handle the OAuth callback and exchange code for tokens49exports.etsyOauthCallback = functions.https.onRequest(async (req, res) => {50 const { code, state } = req.query;51 if (!code || !state) {52 res.status(400).send('Missing code or state');53 return;54 }5556 const stateDoc = await db.collection('etsyPkceState').doc(state).get();57 if (!stateDoc.exists) { res.status(400).send('Invalid or expired state'); return; }5859 const { verifier, userId } = stateDoc.data();60 await stateDoc.ref.delete(); // Single use6162 try {63 const tokenResp = await axios.post(TOKEN_URL, new URLSearchParams({64 grant_type: 'authorization_code',65 client_id: KEYSTRING,66 redirect_uri: REDIRECT_URI,67 code,68 code_verifier: verifier,69 }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });7071 const { access_token, refresh_token, expires_in } = tokenResp.data;7273 // Persist refresh token per user in Firestore74 await db.collection('users').doc(userId).collection('etsyTokens').doc('primary').set({75 refresh_token,76 updatedAt: admin.firestore.FieldValue.serverTimestamp(),77 });7879 // Return access token + expiry to FlutterFlow via deep link or redirect80 res.redirect(81 `your-app-scheme://etsy-callback?access_token=${access_token}&expires_in=${expires_in}`82 );83 } catch (error) {84 res.status(500).send(`Token exchange failed: ${error.message}`);85 }86});8788// Step 3: Refresh the access token (called from FlutterFlow before it expires)89exports.etsyRefreshToken = functions.https.onRequest(async (req, res) => {90 res.set('Access-Control-Allow-Origin', '*');91 if (req.method === 'OPTIONS') { res.status(204).send(''); return; }9293 const { userId } = req.body;94 if (!userId) { res.status(400).json({ error: 'userId required' }); return; }9596 const tokenDoc = await db.collection('users').doc(userId).collection('etsyTokens').doc('primary').get();97 if (!tokenDoc.exists) { res.status(404).json({ error: 'No token found for user' }); return; }9899 const { refresh_token } = tokenDoc.data();100 try {101 const tokenResp = await axios.post(TOKEN_URL, new URLSearchParams({102 grant_type: 'refresh_token',103 client_id: KEYSTRING,104 refresh_token,105 }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });106 res.status(200).json({107 access_token: tokenResp.data.access_token,108 expires_in: tokenResp.data.expires_in,109 });110 } catch (error) {111 res.status(401).json({ error: 'Refresh failed — user must re-authorize' });112 }113});114Pro tip: The etsyOauthCallback function redirects to a custom deep-link URI (your-app-scheme://etsy-callback). Configure this URI scheme in FlutterFlow under Settings → App Details → Deep Links, and add a handler on your main page that reads the access_token from the incoming deep link and stores it in App State.
Expected result: All three Cloud Functions deploy successfully. Calling /etsyAuthUrl returns a valid Etsy authorization URL. Visiting that URL in a browser shows the Etsy consent screen.
Launch the Etsy consent screen and capture the access token
With the Cloud Functions deployed, wire up the Etsy login flow in FlutterFlow. Create a ConnectEtsy page with a Connect My Etsy Shop button. In the button's Action Flow, add a Backend/API Call action that calls your EtsyAuth API Group → GetAuthUrl (set up in the next step) with the logged-in user's Firebase UID. Store the returned authUrl in a page state variable. Then add a Launch URL action pointing to the authUrl variable. This opens the Etsy consent screen in the device's browser. On the consent screen, the seller approves access, Etsy redirects to your etsyOauthCallback function which exchanges the code and stores the refresh token in Firestore, then redirects the user back to your app via the deep link URI with the access token in the URL parameters. In FlutterFlow, configure deep link handling: go to Settings → App Details → Deep Links. Add your custom scheme (e.g. etsyapp://etsy-callback). On the page that receives this deep link — typically your home page or the ConnectEtsy page — add an On Deep Link action that reads the access_token and expires_in parameters from the deep link URL. Store the access_token in App State (String variable: etsyAccessToken) and calculate the expiry timestamp (current time + expires_in seconds) and store it in another App State variable (etsyTokenExpiry as an integer Unix timestamp). Also store the Firebase user ID in App State — you'll need it to call the RefreshToken function. Once the access token is stored in App State, navigate automatically to the seller dashboard. You don't need to display the token anywhere in the UI.
Pro tip: Configure your deep link custom scheme in both FlutterFlow AND your Etsy app's registered redirect URI — they must match exactly. If the redirect URI registered with Etsy doesn't match what the Cloud Function sends, the OAuth flow will fail with an invalid_redirect_uri error.
Expected result: Tapping Connect My Etsy Shop opens the Etsy consent screen, the seller approves, the app receives the deep link, and the access token is stored in App State. The app navigates to the dashboard.
Create the Etsy API Group with both required headers
In FlutterFlow, click API Calls in the left nav → + Add → Create API Group. Name it EtsyOpenAPI. Set the Base URL to https://openapi.etsy.com/v3. This is where the critical dual-header setup happens. In the Group Headers section, add BOTH of the following headers — both are mandatory on every Etsy v3 API call: 1. Header name: x-api-key, value: your actual Etsy keystring (the alphanumeric API key from developers.etsy.com). Unlike the Bearer token, the keystring doesn't change per user or per session — it's your app's static credential. You can store it in App Values for cleanliness. 2. Header name: Authorization, value: Bearer {{accessToken}} — make accessToken a Group-level variable so you can pass the current App State value to all calls. Add your first API Call inside the group: name it GetShopListings. Method: GET. Endpoint: /application/shops/{{shopId}}/listings/active. Variables: shopId (String), limit (Integer, default 25), offset (Integer, default 0). The shopId comes from a separate Etsy API call to get the authenticated user's shop — add a second API Call named GetMe: GET /application/users/me — this returns the seller's shop_id that you'll store in App State after the OAuth flow completes. Add a third API Call named GetShopReceipts (orders): GET /application/shops/{{shopId}}/receipts. Variables: shopId, was_paid (Boolean filter), limit (25), offset (0). Open Response & Test for each call, fill in a test shopId and your access token in the accessToken variable field, and click Test API Call. If you get 401, verify BOTH headers are present — x-api-key AND Authorization.
1{2 "API Group": "EtsyOpenAPI",3 "Base URL": "https://openapi.etsy.com/v3",4 "Group Headers": {5 "x-api-key": "YOUR_ETSY_KEYSTRING",6 "Authorization": "Bearer {{accessToken}}"7 },8 "Group Variables": [9 { "name": "accessToken", "type": "String" }10 ],11 "API Calls": [12 {13 "Name": "GetMe",14 "Method": "GET",15 "Endpoint": "/application/users/me"16 },17 {18 "Name": "GetShopListings",19 "Method": "GET",20 "Endpoint": "/application/shops/{{shopId}}/listings/active",21 "Variables": [22 { "name": "shopId", "type": "String" },23 { "name": "limit", "default": "25" },24 { "name": "offset", "default": "0" }25 ]26 },27 {28 "Name": "GetShopReceipts",29 "Method": "GET",30 "Endpoint": "/application/shops/{{shopId}}/receipts",31 "Variables": [32 { "name": "shopId", "type": "String" },33 { "name": "was_paid", "type": "Boolean", "default": "true" },34 { "name": "limit", "default": "25" },35 { "name": "offset", "default": "0" }36 ]37 }38 ]39}40Pro tip: After the OAuth flow completes, call GetMe immediately to retrieve the seller's shopId and primary email, then store the shopId in App State. You'll need it for every subsequent Etsy API call — don't ask the seller to type in their shop ID.
Expected result: All three API Calls in EtsyOpenAPI return data successfully in the Response & Test panel when both x-api-key and a valid Bearer accessToken are present.
Build the seller dashboard and implement token refresh
Create a SellerDashboard page as the home page after OAuth login. Add a bottom navigation bar with two tabs: Listings and Orders. On the Listings tab: add a ListView bound via Backend Query to EtsyOpenAPI → GetShopListings, passing the shopId from App State and the etsyAccessToken from App State as the accessToken variable. Inside the ListView, add a Card with: a 100x100 Image widget (bind to $.results[0].images[0].url_75x75 from the listing JSON), a Text widget for listing title ($.results[0].title), and a Text widget for price ($.results[0].price.amount formatted as currency). Map these JSON Paths in the Response & Test panel of GetShopListings using a real API response. On the Orders/Receipts tab: add a ListView bound to EtsyOpenAPI → GetShopReceipts. Create a Shift4Order-style Data Type for Etsy receipts: receiptId (Integer), buyerEmail (String), grandtotal (Double), status (String), createTimestamp (Integer). Inside the Card show receipt ID, buyer name, total, and a formatted date. Token refresh logic: Add a proactive check before firing any EtsyOpenAPI call. Create an App State variable etsyTokenExpiry (Integer). In the Action Flow before any listing or receipt query, add a condition: if current timestamp > etsyTokenExpiry - 300 (5 minutes before expiry), first call your Cloud Function's /etsyRefreshToken endpoint (via a separate API Group pointing at your Cloud Function), update etsyAccessToken and etsyTokenExpiry in App State, then proceed with the Etsy API call. Etsy's daily request limit (verify current limit at developers.etsy.com) means you should avoid polling or auto-refreshing listing data more than needed. Cache the listing array in App State between sessions using Firestore persistence, and only reload on explicit user pull-to-refresh gesture.
Pro tip: If you'd rather skip building the OAuth PKCE flow and token management infrastructure yourself, RapidDev's team builds FlutterFlow integrations with Etsy's API regularly and can handle the authentication architecture — request a free scoping call at rapidevelopers.com/contact.
Expected result: The seller dashboard shows active Etsy listings and recent orders fetched from the Etsy Open API, with proactive token refresh preventing 401 errors mid-session.
Common use cases
Etsy seller order and listing dashboard
An Etsy shop owner builds a FlutterFlow app as their primary mobile interface for managing their shop. After completing the Etsy OAuth login, the app displays active listings with view counts and favorites, incoming orders sorted by date, and receipt details for order fulfillment — all fetched from Etsy Open API v3 with both required headers.
A seller dashboard with a bottom nav: Listings tab showing active product listings with thumbnail, title, quantity, and price; Orders tab showing new and open receipts sorted by date with buyer name and order total; Shop tab showing shop stats (views, revenue, favorites).
Copy this prompt to try it in FlutterFlow
Multi-seller Etsy management platform
A social selling manager oversees multiple Etsy shops for different clients. Each seller logs in separately through the Etsy OAuth consent screen, and the app stores each seller's refresh token per-user in Firestore under their Firebase Auth UID. Switching between seller accounts is as simple as selecting a shop from a dropdown, which loads that seller's token and fetches their shop-specific data.
An app with a shop selector screen showing all connected Etsy shops (each with shop name and avatar), a connect new shop button that launches the Etsy OAuth flow, and a per-shop dashboard with listings and orders that updates when the user switches between shops.
Copy this prompt to try it in FlutterFlow
Etsy listing performance tracker
An Etsy seller wants to track which listings get the most views and favorites over time. The app uses the Etsy API to fetch listing data including view counts and favorited counts, caches results in Firestore with timestamps, and displays trend charts showing which listings are gaining or losing visibility.
A listing analytics screen with a sorted list of active listings ranked by view count, a sparkline chart per listing showing views over the last 30 days, a favorites counter, and a tap-through to the listing detail with full stats.
Copy this prompt to try it in FlutterFlow
Troubleshooting
401 Unauthorized from every Etsy API call despite having a valid access token
Cause: The x-api-key header is missing. Etsy Open API v3 requires BOTH x-api-key (your keystring) AND Authorization: Bearer [token] on every call. Missing either one returns 401 with no distinction between the two missing values.
Solution: Open the EtsyOpenAPI API Group in FlutterFlow → API Calls panel → select the group headers. Verify that BOTH headers are present: x-api-key set to your Etsy keystring value, and Authorization set to Bearer {{accessToken}}. In the Response & Test panel, manually fill in the accessToken variable with a valid token and confirm x-api-key is hard-set or passed correctly. Test the call — if you get a response, the headers are now correct.
Etsy consent screen shows an invalid_redirect_uri error
Cause: The redirect_uri in the Cloud Function's authorization URL does not exactly match the redirect URI registered in your Etsy developer app settings.
Solution: In the Etsy developer portal (developers.etsy.com), go to your app settings and verify the registered redirect URI. Copy it exactly and update the ETSY_REDIRECT_URI environment variable in your Cloud Function configuration to match. Etsy performs an exact string match — trailing slashes, http vs https, and case all matter.
Listing data loads initially but 401 errors appear after 30-60 minutes of use
Cause: The Etsy access token has expired. Tokens are short-lived and must be refreshed using the refresh token stored in Firestore via the Cloud Function.
Solution: Verify the proactive token refresh logic is in place (Step 5): before any EtsyOpenAPI call, check if the current timestamp is within 300 seconds of etsyTokenExpiry, and call the Cloud Function's /etsyRefreshToken endpoint if so. If refresh fails (the refresh token itself has expired), show the user a 'Reconnect Etsy' button that re-launches the OAuth consent flow.
Daily request quota is exhausted before end of day due to ListView scrolling
Cause: FlutterFlow ListViews with Backend Query set to auto-load fire API calls on every rebuild. If listing data is loaded per scroll position without caching, a user scrolling through many listings can exhaust the 10,000 daily request limit.
Solution: Implement caching: load the full active listings array once per session into an App State list variable. Use pagination with limit/offset and store each page in the list variable as the user scrolls, rather than firing a fresh API call for each page view. Add a refresh button for manual refresh instead of auto-reloading. Consider persisting the listing cache in Firestore with a timestamp so it survives app restarts.
Best practices
- Always include BOTH the x-api-key header (your Etsy keystring) AND the Authorization: Bearer [token] header on every Etsy v3 API call — missing either returns 401 with no helpful error message.
- Keep the OAuth PKCE code exchange in the Firebase Cloud Function — doing it in Dart client code exposes the code_verifier to extraction and makes secure refresh token storage impossible.
- Store refresh tokens per Firebase user ID in Firestore, never in FlutterFlow App State — App State is cleared on app restart, which would force the seller to re-authorize every time they close the app.
- Implement proactive token refresh (check expiry 5 minutes before it occurs) rather than reacting to 401 errors — a mid-session 401 on the orders screen creates a confusing experience for sellers.
- Cache Etsy listing data aggressively in App State between pages and sessions — Etsy's daily request limit is easy to exhaust if every screen load fires fresh API calls.
- Request only the OAuth scopes your app actually uses (listings_r, transactions_r, shops_r) — requesting unnecessary scopes reduces Etsy's likelihood of approving your app for commercial use.
- Call GetMe immediately after the OAuth flow to retrieve and cache the seller's shopId — every other Etsy endpoint requires it, and making sellers type their shop ID is poor UX.
- Test your token refresh logic explicitly by manually setting etsyTokenExpiry to a past timestamp and confirming the refresh fires and updates the token before the next API call.
Alternatives
Spocket uses a simpler Bearer-only API key (no OAuth PKCE or x-api-key dual header) — a better choice if you need catalog browsing without per-seller authorization flows.
SFCC uses a similar SLAS OAuth 2.0 PKCE architecture but for enterprise retail with org-scoped tokens rather than per-seller consent — significantly more complex than Etsy for a larger scale.
eBay's API provides a similar OAuth 2.0 authorization code flow for marketplace sellers but with better commercial API access for larger transaction volumes than Etsy's 10,000 requests/day limit.
Frequently asked questions
Why do I need both x-api-key AND Authorization headers on every Etsy v3 call?
Etsy uses a two-layer authentication model: the x-api-key identifies your application (like an app registration), while the Authorization: Bearer token identifies which seller has authorized your app to access their shop. Both layers are required because Etsy needs to know both which application is making the request and which seller granted access. This is unusual compared to most OAuth APIs that combine both into the OAuth token alone.
Can I use the Etsy API to help multiple different Etsy sellers from one FlutterFlow app?
Yes — this is the multi-seller platform use case. Each seller completes the OAuth consent flow separately, and their refresh token is stored in Firestore under their Firebase Auth user ID. Your single Etsy app keystring (x-api-key) is shared across all sellers since it identifies your application, but each seller's Bearer access token is unique. When switching between sellers in the UI, swap the accessToken and shopId values in App State to switch which seller's data is being displayed.
Does the Etsy API work for listing analytics or only for listing management?
Etsy Open API v3 provides listing data including view counts and favorite counts on individual listings, which you can trend over time by polling and caching in Firestore. However, Etsy does not provide aggregated shop analytics (like Google Analytics-style dashboards) through the API — those are only available in the Etsy seller dashboard on the web. For trend data, your app would need to periodically fetch listing stats and store them in Firestore to build a historical view.
What happens when the refresh token expires?
Etsy refresh tokens have their own expiry (verify the current duration in Etsy's developer documentation). If a refresh token expires, the /etsyRefreshToken Cloud Function call will return a 401, and you must prompt the seller to complete the full OAuth consent flow again. In your FlutterFlow app, catch the 401 from the refresh endpoint and show a 'Your Etsy connection has expired — please reconnect' screen with the Connect My Etsy Shop button.
Is Etsy API access free to use?
Yes, registering at developers.etsy.com and using the API is free. Standard rate limits apply (verify current limits in the Etsy developer documentation). If you're building a commercial product that will be used by many Etsy sellers or requires higher request volumes, Etsy requires a commercial API access application — contact Etsy's developer support to apply.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation