Connect Bubble to Etsy Open API v3 by configuring the API Connector with TWO mandatory headers on every call — x-api-key (your keystring, marked Private) and Authorization: Bearer {access_token}. Missing either header returns a cryptic 401. Build the PKCE OAuth flow manually via Backend Workflows since Bubble's native OAuth connector does not support PKCE. Set up a Recurring Backend Workflow to refresh the 1-hour access token automatically.
| Fact | Value |
|---|---|
| Tool | Etsy API |
| Category | E-commerce |
| Method | Bubble API Connector |
| Difficulty | Advanced |
| Time required | 4–6 hours |
| Last updated | July 2026 |
The Dual-Header API That Trips Every First-Time Builder
Etsy's Open API v3 has a security requirement that is genuinely unusual among e-commerce APIs: every single request must include both an x-api-key header (your static application keystring, always the same regardless of which user is logged in) AND an Authorization: Bearer header (a user-specific access token obtained through OAuth). Most OAuth APIs require only the Bearer token. Etsy requires both simultaneously, and when either is missing, the 401 response gives no indication of which header caused the failure. In Bubble, you solve this by configuring the API Connector group with both headers — x-api-key marked Private so it stays server-side, and Authorization as a shared header where the token is a dynamic parameter your app passes per-call using the token stored for the current logged-in user. The second significant complexity is the OAuth flow itself. Etsy v3 uses PKCE (Proof Key for Code Exchange), which is a security enhancement over standard OAuth that adds a code_verifier/code_challenge pair to the authorization flow. Bubble's built-in OAuth connector does not support PKCE, so the entire flow — generating the state and code_verifier, constructing the authorization URL, handling the redirect callback, exchanging the authorization code for tokens — must be built manually using Bubble Backend Workflows. Backend Workflows (API Workflows) are a paid Bubble plan feature, so this integration requires a paid subscription. Access tokens expire after one hour, meaning a Recurring Backend Workflow that proactively refreshes tokens every 50 minutes is essential for any production app. Once this auth infrastructure is in place, the Etsy API is straightforward to work with: endpoints for listing management, order/receipt retrieval, and shop analytics are well-documented at developers.etsy.com.
Integration method
The Bubble API Connector calls Etsy Open API v3 at https://openapi.etsy.com/v3 with two mandatory shared headers — x-api-key (Private) and Authorization: Bearer {access_token} — and Backend Workflows manage the PKCE token exchange and hourly token refresh.
Prerequisites
- An Etsy seller account with at least one active shop — required to access shop-specific API endpoints like listings and receipts
- An Etsy developer app registered at developers.etsy.com — this generates your keystring (used as both the OAuth client_id and the x-api-key header value)
- A Bubble app on a paid plan — Backend Workflows (API Workflows) are required for the PKCE OAuth token exchange and the Recurring token refresh; these features are not available on Bubble's Free plan
- The API Connector plugin installed in your Bubble app — free, published by Bubble
- Familiarity with Bubble workflows and data types — this integration is rated Advanced and involves multi-step OAuth flows and token storage patterns
Step-by-step guide
Register Your Etsy Developer App and Note Your Credentials
Go to developers.etsy.com and sign in with your Etsy account. Navigate to 'Your apps' and click 'Create a new app'. Give your app a name and description. Under the Callback URLs section, add the URL where Etsy will redirect users after authorization — in Bubble, this is your app's URL followed by a page route, for example: https://yourapp.bubbleapps.io/etsy-callback. After creating the app, Etsy displays your keystring on the app detail page. Copy the keystring immediately — this value serves double duty: it is your OAuth client_id (used in the authorization URL) and your x-api-key header value (sent on every API request). Note which OAuth scopes you need: for a seller dashboard with listings and orders, you need at minimum listings_r (read listings), transactions_r (read transactions), and shops_r (read shop info). Etsy does not allow requesting scopes you did not declare at app creation — declare all scopes you may need upfront. If your Etsy app will be used commercially by other sellers (not just your own shop), you must apply for elevated API access through Etsy's developer program — the default registration allows access for testing and personal use.
1// Etsy OAuth scopes needed for a seller dashboard2// Add these as space-separated values in the authorization URL scope parameter3// listings_r — read listing data4// transactions_r — read transaction / receipt data5// shops_r — read shop information6// listings_w — write (create/update/delete) listings (if needed)7// transactions_w — update transaction data (mark as shipped, etc.)89// Declare all needed scopes when creating your Etsy app — you cannot add scopes later10// without going through Etsy's app review processPro tip: Declare every scope you might need when creating your Etsy developer app. You cannot add OAuth scopes to an existing app without submitting it for re-review by Etsy — planning upfront saves significant delay.
Expected result: You have an Etsy developer app with a keystring (your x-api-key value and OAuth client_id), a configured callback URL pointing to your Bubble app, and the required OAuth scopes declared.
Set Up the API Connector with Both Required Headers
Open your Bubble app editor and go to Plugins tab → Add plugins. Search for 'API Connector' (published by Bubble) and install it. Open the API Connector configuration and click 'Add another API'. Name the group 'Etsy API' and set the root URL to https://openapi.etsy.com/v3. Now add the two headers that Etsy requires on every call. First header: name it x-api-key, value is your Etsy keystring, and check the 'Private' checkbox — this marks it as a server-side header that Bubble will never send to the browser. Second header: name it Authorization, value is 'Bearer [access_token]' where access_token is a parameter you define (use Bubble's parameter bracket notation). Set access_token as a parameter at the API group level so it can be passed from any call that uses this group. This means the access_token will be dynamically injected per-call from your Bubble database — each user's stored token gets passed as this parameter when you trigger an API call. The authorization header must read exactly: Bearer followed by a space and then the token value. Many 401 errors come from missing the space between 'Bearer' and the token, or from sending the token without the 'Bearer ' prefix.
1// Etsy API Connector Group Configuration2{3 "groupName": "Etsy API",4 "rootURL": "https://openapi.etsy.com/v3",5 "sharedHeaders": [6 {7 "name": "x-api-key",8 "value": "YOUR_ETSY_KEYSTRING",9 "private": true10 },11 {12 "name": "Authorization",13 "value": "Bearer <access_token dynamic>",14 "private": false15 },16 {17 "name": "Accept",18 "value": "application/json",19 "private": false20 }21 ],22 "groupParameters": [23 {24 "name": "access_token",25 "description": "Per-user Etsy access token from Bubble DB"26 }27 ]28}Pro tip: The x-api-key and the OAuth client_id are the same keystring value from your Etsy developer app. This is intentional in Etsy's API design — the x-api-key header identifies your application on every request, while the Bearer token identifies the authenticated user.
Expected result: The Etsy API group appears in the API Connector with the x-api-key Private header and the Authorization Bearer header configured. No calls have been added yet — you add those in subsequent steps after setting up the OAuth flow.
Build the PKCE OAuth Authorization Flow Using Backend Workflows
Etsy v3 requires PKCE OAuth, and Bubble's built-in OAuth connector does not support PKCE. You must build the entire authorization flow manually. PKCE adds a code_verifier (a random string) and code_challenge (SHA-256 hash of the code_verifier, base64url encoded) to the standard OAuth code flow. Since Bubble cannot generate SHA-256 hashes natively, use the Toolbox plugin's 'Run javascript' action in a Backend Workflow to generate the PKCE values. Install the Toolbox plugin from Plugins → Add plugins → search 'Toolbox'. Step 1 — Generate state and PKCE: Create a Backend Workflow named 'Etsy_GeneratePKCE'. Inside it, add a 'Run javascript' action (from Toolbox) that generates a random 43-128 character code_verifier string. Store the code_verifier in a Bubble data type named 'EtsyOAuthSession' with fields: code_verifier (text), state (text), user (User), created_date (date). Step 2 — Build authorization URL: Construct the Etsy authorization URL as a text value in a workflow. The URL format is: https://www.etsy.com/oauth/connect?response_type=code&redirect_uri={YOUR_CALLBACK_URL}&scope={SCOPES}&client_id={KEYSTRING}&state={state}&code_challenge={code_challenge}&code_challenge_method=S256. Step 3 — Redirect user: Use Bubble's 'Go to URL' action to send the user to this authorization URL. They will see Etsy's permission screen and authorize your app. Step 4 — Handle callback: On your Etsy callback page (/etsy-callback), the URL will contain 'code' and 'state' query parameters. Extract them from the page URL. Verify the state matches the stored EtsyOAuthSession. Trigger a Backend Workflow that exchanges the code for tokens.
1// JavaScript for Toolbox 'Run javascript' action — generates PKCE code_verifier and code_challenge2// Add this in the Toolbox Run javascript action body3// Output properties: code_verifier (text), code_challenge (text), state (text)45function generateRandomString(length) {6 const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';7 let result = '';8 const array = new Uint8Array(length);9 window.crypto.getRandomValues(array);10 array.forEach(byte => result += chars[byte % chars.length]);11 return result;12}1314async function generatePKCE() {15 const code_verifier = generateRandomString(64);16 const state = generateRandomString(32);17 const encoder = new TextEncoder();18 const data = encoder.encode(code_verifier);19 const digest = await window.crypto.subtle.digest('SHA-256', data);20 const code_challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))21 .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');22 bubble_fn_result({ code_verifier, code_challenge, state });23}2425generatePKCE();Pro tip: Store the code_verifier in the Bubble database (EtsyOAuthSession data type) immediately after generating it — you will need it again during the token exchange step when Etsy calls back to your redirect URL.
Expected result: Users who click 'Connect Etsy' are redirected to Etsy's authorization page. After authorizing, they are redirected back to your Bubble callback page with a 'code' query parameter in the URL. The EtsyOAuthSession record in your database contains the matching code_verifier and state values.
Exchange Authorization Code for Tokens and Store Them Securely
After the user authorizes your Etsy app, Etsy redirects them to your callback URL with a 'code' parameter and the 'state' value. Create a Backend Workflow named 'Etsy_ExchangeCode' that takes the authorization code as an input parameter. This workflow makes a POST call to Etsy's token endpoint: https://api.etsy.com/v3/public/oauth/token. The POST body must include: grant_type=authorization_code, client_id={KEYSTRING}, redirect_uri={YOUR_CALLBACK_URL}, code={authorization_code}, and code_verifier={the stored code_verifier from EtsyOAuthSession}. Set this up as a separate API call in your API Connector — name the group 'Etsy OAuth' with root URL https://api.etsy.com (note: different from the API root https://openapi.etsy.com). The token exchange call does NOT need the x-api-key header — only the form-encoded body parameters. Set the call body as application/x-www-form-urlencoded (not JSON). Etsy returns: access_token (use this for all API calls), refresh_token (save this for renewal), expires_in (seconds — typically 3600). Create a Bubble data type 'EtsyToken' with fields: access_token (text), refresh_token (text), expires_at (date), shop_id (number), user (User). Store all token fields immediately after the exchange. Delete the EtsyOAuthSession record once the exchange succeeds to remove the short-lived code_verifier from your database.
1// Etsy token exchange POST body (application/x-www-form-urlencoded)2grant_type=authorization_code3&client_id=YOUR_ETSY_KEYSTRING4&redirect_uri=https://yourapp.bubbleapps.io/etsy-callback5&code=AUTHORIZATION_CODE_FROM_REDIRECT6&code_verifier=THE_STORED_CODE_VERIFIER78// Etsy token exchange response9{10 "access_token": "etsy-v3-access-token-value",11 "token_type": "Bearer",12 "expires_in": 3600,13 "refresh_token": "etsy-v3-refresh-token-value"14}1516// Store in Bubble EtsyToken data type:17// access_token: response.access_token18// refresh_token: response.refresh_token19// expires_at: Current date/time + 3600 seconds (add 3600 seconds to now)20// user: Current UserPro tip: Calculate expires_at by adding 3600 seconds (1 hour) to the current time at the moment of token exchange. This gives you a timestamp you can check in the refresh workflow to know when the token will expire — check if expires_at is within 5 minutes of now before any API call.
Expected result: After authorization, an EtsyToken record is created in Bubble's database for the user with access_token, refresh_token, and expires_at fields populated. The user can now make authenticated Etsy API calls.
Add and Initialize Etsy API Calls and Build the Seller Dashboard
With authentication working, add API calls to your Etsy API group. Start with the user profile call to confirm both headers work: GET /application/users/me. When initializing this call, use a real access_token value from the EtsyToken record you created in Step 4 — paste it as the access_token parameter during initialization. If initialization succeeds, Bubble detects the user fields. Next, add the active listings call: GET /application/shops/{shopId}/listings/active. The shopId is available from the GET /users/me response (shops array, first item's shop_id field — store it in EtsyToken when you run the initial user lookup). Add parameters: limit (default 25, max 100), offset (for pagination). Initialize with real values. Etsy list responses wrap data in {count, results: [...]} — use results as the data path in Bubble's API Call definition. Add one more call: GET /application/shops/{shopId}/receipts for order management. Use parameters: min_created, max_created (Unix timestamps), status. Now build the seller dashboard page: add a Repeating Group bound to the listings call, passing the current user's shopId and access_token from EtsyToken. Display listing title, price, quantity, and thumbnail image. Add a second section for recent orders bound to the receipts call. Important: Etsy's daily limit is 10,000 requests per app across all your users. A Repeating Group that auto-refreshes on every page load can exhaust this quickly for a popular app — cache listing data in a Bubble data type and refresh it on a schedule or on-demand rather than fetching live for every visitor.
1// Etsy GET /application/users/me response structure (partial)2{3 "user_id": 12345678,4 "primary_email": "seller@example.com",5 "shops": [6 {7 "shop_id": 87654321,8 "shop_name": "MyEtsyShop"9 }10 ]11}1213// Etsy GET /application/shops/{shopId}/listings/active response structure14{15 "count": 48,16 "results": [17 {18 "listing_id": 1234567890,19 "title": "Handmade Ceramic Mug - Ocean Blue",20 "price": { "amount": 2500, "divisor": 100, "currency_code": "USD" },21 "quantity": 5,22 "state": "active",23 "url": "https://www.etsy.com/listing/1234567890/handmade-ceramic-mug",24 "images": [25 { "listing_image_id": 1111, "url_170x135": "https://...", "url_570xN": "https://..." }26 ]27 }28 ]29}Pro tip: Etsy prices are returned as amounts in the smallest currency unit divided by a divisor (e.g., amount=2500 and divisor=100 means $25.00). Always divide amount by divisor to get the display price — do not display the raw amount value to users.
Expected result: The Etsy API Connector has initialized calls for user profile and shop listings. The seller dashboard page displays the authenticated seller's active listings with titles, prices, and images. Recent orders appear in the orders section.
Set Up Recurring Token Refresh to Prevent Expiry
Etsy access tokens expire after exactly one hour. Any API call made with an expired token returns a 401 error, breaking your app for logged-in users. The solution is a Recurring Backend Workflow that proactively refreshes the token before it expires. Add a new API call to your 'Etsy OAuth' group: POST to https://api.etsy.com/v3/public/oauth/token with grant_type=refresh_token, client_id={KEYSTRING}, refresh_token={stored_refresh_token}. Etsy returns a new access_token and refresh_token pair. Create a Backend Workflow named 'Etsy_RefreshToken' that takes a user as input. It calls the refresh token endpoint with that user's stored refresh_token, then updates the EtsyToken record: set access_token to the new value, set refresh_token to the new value (Etsy rotates refresh tokens), and set expires_at to current time + 3600 seconds. Create a Recurring Backend Workflow (Settings → Backend Workflows → Recurring events in Bubble) that runs every 50 minutes. This workflow searches for all EtsyToken records where expires_at is within the next 10 minutes and calls 'Etsy_RefreshToken' for each one. Alternatively, you can add a token freshness check at the beginning of any workflow that makes an Etsy API call: if the current user's EtsyToken expires_at is within 5 minutes of now, run the refresh before making the API call. Both approaches are valid; the Recurring Backend Workflow is more reliable for apps with many concurrent users. Note: Recurring Backend Workflows require a paid Bubble plan and consume Workload Units — budget for this when planning your Bubble subscription tier. If you have complex questions about building this auth infrastructure for a production Etsy integration, RapidDev's team can help plan the architecture — free scoping call at rapidevelopers.com/contact.
1// Etsy token refresh POST body (application/x-www-form-urlencoded)2grant_type=refresh_token3&client_id=YOUR_ETSY_KEYSTRING4&refresh_token=THE_STORED_REFRESH_TOKEN56// Etsy refresh token response7{8 "access_token": "new-etsy-access-token",9 "token_type": "Bearer",10 "expires_in": 3600,11 "refresh_token": "new-etsy-refresh-token"12}1314// IMPORTANT: Etsy rotates refresh tokens on each use.15// Always save the NEW refresh_token from the response — the old one is invalidated.16// Update EtsyToken record:17// access_token = response.access_token18// refresh_token = response.refresh_token (NEW value)19// expires_at = now + 3600 secondsPro tip: Etsy rotates refresh tokens — each time you use a refresh token, Etsy invalidates it and returns a new one. Always save the new refresh_token value from the refresh response to your EtsyToken record, or the next refresh attempt will fail with an 'invalid_grant' error.
Expected result: The Recurring Backend Workflow runs every 50 minutes and refreshes EtsyToken records for users whose tokens are expiring soon. Users stay logged in indefinitely without seeing 401 errors from expired tokens.
Common use cases
Etsy Seller Dashboard
Build a custom admin panel in Bubble for Etsy shop owners to view their active listings, pending orders, and recent transactions in a consolidated interface. Pull active listings from the Etsy listings API and receipts from the transactions API to give sellers a single-screen view without logging into Etsy's native dashboard.
Show all active listings in my Etsy shop sorted by number of sales descending, with the listing image, title, price, and current quantity.
Copy this prompt to try it in Bubble
Multi-Shop Analytics Tool
Allow multiple Etsy sellers to connect their shops to your Bubble app using the OAuth flow. Each seller authorizes their own account, stores their own access token in your Bubble database, and can view shop-specific analytics — revenue trends, top-selling listings, order fulfillment rates — pulled live from the Etsy API.
Show me the total revenue and number of orders for my Etsy shop for each of the last 6 months, broken down by listing category.
Copy this prompt to try it in Bubble
Automated Order Fulfillment Tracker
Build a Bubble workflow that checks new Etsy receipts on a schedule, creates fulfillment records in Bubble's database, and sends internal notifications (via Slack or email) when new orders arrive. Update order fulfillment status back to Etsy via the receipts API when items ship.
Show all unshipped Etsy orders from the last 30 days with the buyer's name, shipping address, and ordered items listed.
Copy this prompt to try it in Bubble
Troubleshooting
API calls return HTTP 401 even though the Bearer token looks correct
Cause: The x-api-key header is missing, incorrectly spelled, or has the wrong value. Etsy v3 requires BOTH x-api-key and Authorization: Bearer simultaneously — a missing x-api-key returns the same 401 as a bad Bearer token, with no distinction in the error message.
Solution: Open the API Connector group configuration and verify that x-api-key is spelled exactly lowercase (not X-Api-Key, not X-API-KEY), that the value is your Etsy keystring (not the OAuth client secret — there is only one credential: the keystring), and that the Private checkbox is checked. Re-initialize a simple call like GET /application/users/me with your stored access_token to confirm both headers are working together.
'There was an issue setting up your call' during Initialize — no fields detected
Cause: The access_token value you used during initialization was expired (tokens last 1 hour) or the token does not have the required OAuth scope for the endpoint you are initializing.
Solution: Complete the OAuth flow fresh (Steps 3 and 4) to get a new access_token, then use that value during initialization. For the /listings endpoint, ensure your Etsy app was created with the listings_r scope. Initialize with /application/users/me first (requires no shop-specific scope) to confirm the headers are valid, then initialize the more specific endpoints.
Token exchange fails with 'invalid_grant' or 'invalid_client'
Cause: The authorization code from Etsy has already been used (codes are single-use), the code_verifier does not match the code_challenge submitted in the authorization URL, or the redirect_uri in the token exchange does not exactly match the one registered in your Etsy developer app.
Solution: Restart the OAuth flow completely: generate a new code_verifier and state, redirect the user to Etsy's authorization page again, and use the new authorization code immediately on the callback. Verify that the redirect_uri in the token exchange POST body is character-for-character identical to the one listed in your Etsy app settings — trailing slashes and http vs https differences matter.
App stops working with 401 errors after about 1 hour of use
Cause: The Etsy access token expired after 1 hour and the refresh flow is not running, not finding the right record, or using an already-rotated refresh_token.
Solution: Check your Recurring Backend Workflow in Bubble's Workflow Logs. If it is not running, verify it is scheduled and that your Bubble plan supports recurring events. If it is running but failing, check the EtsyToken record — Etsy rotates refresh_tokens on each use, so if a previous refresh ran but did not save the new refresh_token, the stored token is now invalid. Run a fresh OAuth flow for the affected user to get a new token pair.
API returns 429 Too Many Requests during peak usage
Cause: Etsy allows 10 requests per second and 10,000 requests per day per application. A Bubble Repeating Group that auto-fetches listing data on every page load for multiple users can exhaust the daily limit quickly.
Solution: Cache Etsy listing data in a Bubble data type (sync on demand or on a schedule, not live per page load). For the daily request count, implement a simple counter in a Bubble database field that increments per API call — alert your team when nearing the limit. For per-second rate limiting, add a Wait action (0.5-1 second) between API calls in loops within Backend Workflows.
Best practices
- Always configure BOTH the x-api-key and Authorization: Bearer headers in your API Connector group — missing either one causes a 401 with no indication of which header is the problem.
- Store Etsy access_token and refresh_token in a dedicated Bubble data type (e.g., EtsyToken) with privacy rules that restrict access to the token's owner — never expose tokens in page URL parameters or client-visible state.
- Set up a Recurring Backend Workflow to refresh access tokens every 50 minutes — do not wait for a 401 error to trigger the refresh, as this breaks the current user's session mid-interaction.
- Always save the NEW refresh_token returned from each refresh call — Etsy rotates refresh tokens, and failing to update the stored value will break the next refresh.
- Cache Etsy listing and order data in Bubble's database for frequently viewed content. The 10,000 requests per day per app limit is easy to exhaust with a popular app that fetches live data for every page load.
- Request only the OAuth scopes your app actually needs when creating your Etsy developer app. Additional scopes can only be added through Etsy's app review process — plan ahead rather than starting with minimal scopes.
- Apply Bubble privacy rules to your EtsyToken data type immediately after creating it. By default all authenticated Bubble users can read all records of a given type — restrict EtsyToken access to the Current User whose record it is.
- Test the token expiry and refresh flow in development before launching — manually expire a token (by editing the expires_at field to a past date) and confirm the refresh workflow picks it up and the user can continue making API calls without re-authorizing.
Alternatives
WooCommerce uses a simpler consumer key and secret authentication (no PKCE, no token expiry) and runs on your own WordPress hosting. If you want to sell handmade or vintage goods but prefer simpler API auth for your Bubble integration, WooCommerce's authentication is much easier to implement. Choose Etsy API when your products are already on Etsy and you need to connect Etsy's buyer marketplace to a Bubble tool for your sellers.
eBay also uses OAuth 2.0 but with a simpler single Bearer token header and support for application-level tokens (not user-specific PKCE) for public endpoints. eBay is aimed at general marketplace sellers across electronics, collectibles, and mass-market goods; Etsy is specific to handmade, vintage, and craft products. If your target sellers are on eBay rather than Etsy, the eBay API integration in Bubble is simpler from an auth perspective.
Printful is a print-on-demand fulfillment service rather than a marketplace. If your Bubble app needs to manage print-on-demand products and automate fulfillment for Etsy orders, connecting Printful (for production and shipping) alongside the Etsy API (for order intake) gives you a complete headless commerce workflow. Printful uses a single API key header — much simpler auth than Etsy.
Frequently asked questions
Do I need a paid Bubble plan to connect to the Etsy API?
Yes, for a complete and production-ready integration. The PKCE OAuth token exchange and the Recurring token refresh both require Backend Workflows (API Workflows), which are only available on paid Bubble plans. If you only need read-only access for your own shop (using a pre-obtained static token), you could set up API calls without Backend Workflows — but the token expires every hour and you would need to manually refresh it, which is not practical for a production app.
Why does Etsy require two headers (x-api-key and Authorization) when most APIs only need one?
Etsy's dual-header design separates application identity from user identity. The x-api-key identifies your registered developer application to Etsy — it is the same on every call regardless of which user is logged in. The Authorization Bearer token identifies the specific Etsy user (shop owner) who has authorized your app. Together they let Etsy track both per-app usage (for rate limiting and compliance) and per-user permissions (for security and scope enforcement).
Can I use Bubble's built-in OAuth connector for Etsy?
No. Bubble's native OAuth connector does not support PKCE (Proof Key for Code Exchange), which Etsy v3 requires. The PKCE flow adds a code_verifier and code_challenge to the authorization URL, and the code_verifier must be sent during token exchange. You must build this flow manually using Bubble Backend Workflows and the Toolbox plugin's 'Run javascript' action to generate the PKCE values using the browser's Web Crypto API.
What happens if I do not refresh the Etsy access token?
After one hour, all Etsy API calls made with the expired token return HTTP 401 errors, breaking any workflow in your Bubble app that depends on the Etsy API. Users would need to re-authorize through the OAuth flow to get a new token. For a production app with active users, proactive token refresh via a Recurring Backend Workflow is mandatory — treat it as a core infrastructure component, not an optional enhancement.
Can I build an Etsy integration for multiple sellers (a multi-tenant app)?
Yes — the architecture described here supports multiple sellers. Each seller who connects their Etsy shop goes through the OAuth flow, and their tokens are stored as separate EtsyToken records linked to their Bubble User record. Your API calls pass the current user's stored token as the access_token parameter. The Recurring Backend Workflow refreshes all EtsyToken records that are approaching expiry, regardless of which user they belong to. The Etsy 10,000 requests per day limit applies across ALL users of your app combined — plan your caching strategy accordingly.
How do I get my Etsy shop ID to use in API calls?
After completing the OAuth flow, call GET /application/users/me with the user's access_token. The response includes a 'shops' array — the first item's 'shop_id' field is the numeric shop ID you need for all subsequent shop-specific endpoints like /application/shops/{shopId}/listings/active. Store the shop_id in the EtsyToken data type record alongside the tokens so you do not need to fetch it on every request.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation