Use the Etsy v3 API to pull shop receipts and transactions for any date range and aggregate them into revenue reports. Schedule a daily job with GET /shops/{shop_id}/receipts filtered by created_timestamp, calculate totals by SKU and date, and export to Google Sheets or a database automatically.
| Fact | Value |
|---|---|
| Platform | Etsy |
| Auth method | OAuth 2.0 with mandatory PKCE |
| Rate limits | 10 req/sec, 10,000 req/day (new apps: 5/sec, 5,000/day) |
| Difficulty | Intermediate |
| Time required | 45–60 minutes |
| Last updated | May 2026 |
API Quick Reference
OAuth 2.0 with mandatory PKCE
10 req/sec, 10,000 req/day (new apps: 5/sec, 5,000/day)
JSON
REST only
API overview
https://openapi.etsy.com/v3/applicationAuthentication
All Etsy v3 API requests require two headers: Authorization: Bearer {access_token} and x-api-key: {keystring}. Access tokens expire in 1 hour. Use refresh tokens (valid 90 days) to renew automatically. For reporting automation, store the refresh token in a secrets manager and implement silent refresh before each batch job run.
Key endpoints
/shops/{shop_id}/receiptsReturns paginated receipts with was_paid filter and optional date range via min_created/max_created (Unix timestamps). Each receipt includes grand_total, total_price, total_tax_cost, total_shipping_cost, and an array of transactions.
| Parameter | Type | Required | Description |
|---|---|---|---|
| optional | ||
| optional | ||
| optional | ||
| optional | ||
| optional | ||
| optional |
/shops/{shop_id}/transactionsReturns individual transactions (line items) with listing, quantity, price, and buyer info. More granular than receipts for product-level reporting.
| Parameter | Type | Required | Description |
|---|---|---|---|
| optional | ||
| optional | ||
| optional |
/shops/{shop_id}/receipts/{receipt_id}Fetches a single receipt with full detail. Useful for reconciling a specific order in your reporting pipeline.
| Parameter | Type | Required | Description |
|---|---|---|---|
| optional | ||
| optional |
/listings/{listing_id}Returns listing details including title, tags, and taxonomy. Use to enrich transaction data with product category for category-level reporting.
| Parameter | Type | Required | Description |
|---|---|---|---|
| optional |
Step-by-step automation
Refresh Token and Validate Authentication
Start each scheduled report job by refreshing the access token. The token expires in 1 hour, so any long-running batch that doesn't refresh mid-run will fail partway through.
1# Refresh the access token2curl -X POST https://api.etsy.com/v3/public/oauth/token \3 -H "Content-Type: application/x-www-form-urlencoded" \4 -d "grant_type=refresh_token&client_id=$ETSY_KEYSTRING&refresh_token=$ETSY_REFRESH_TOKEN"56# Test with a simple shops/me call7curl -X GET https://openapi.etsy.com/v3/application/users/me \8 -H "Authorization: Bearer $ETSY_ACCESS_TOKEN" \9 -H "x-api-key: $ETSY_KEYSTRING"Paginate Through Receipts for a Date Range
Fetch all paid receipts within a date range using min_created and max_created Unix timestamps. Paginate with limit=100 and incrementing offset until all records are collected. Etsy prices use sub-unit amounts (amount/divisor = real price).
1# Get receipts for a specific day (Unix timestamps)2# May 22, 2026 00:00:00 UTC = 17480448003# May 22, 2026 23:59:59 UTC = 17481311994curl -X GET "https://openapi.etsy.com/v3/application/shops/$SHOP_ID/receipts?was_paid=true&min_created=1748044800&max_created=1748131199&limit=100" \5 -H "Authorization: Bearer $ETSY_ACCESS_TOKEN" \6 -H "x-api-key: $ETSY_KEYSTRING"Aggregate Revenue Data by Product and Date
Transform raw receipt data into a structured report. Convert sub-unit prices (amount/divisor) to real currency values. Aggregate by listing_id for product-level totals.
1# No direct curl equivalent — aggregation is done in code after fetching dataExport Report to Google Sheets or Database
Write the aggregated report to your destination — Google Sheets via Sheets API, a PostgreSQL table, or a CSV file. Schedule the full pipeline as a daily cron job to run automatically each morning.
1# Write to a Google Sheets range via Sheets API v42curl -X PUT "https://sheets.googleapis.com/v4/spreadsheets/$SPREADSHEET_ID/values/Sales!A1?valueInputOption=USER_ENTERED" \3 -H "Authorization: Bearer $GOOGLE_ACCESS_TOKEN" \4 -H "Content-Type: application/json" \5 -d '{6 "values": [7 ["Date", "Orders", "Total Revenue", "Net Revenue", "Tax", "Shipping"],8 ["2026-05-22", "47", "1423.50", "1198.40", "142.35", "82.75"]9 ]10 }'Complete working code
Complete daily sales report automation. Fetches yesterday's Etsy receipts, aggregates by product and date, and writes to Google Sheets. Schedule with cron.
Error handling
Access token expired (1-hour TTL) or both required headers not included. Etsy requires Authorization: Bearer AND x-api-key on every request.
Implement token refresh at the start of each job. Call the /oauth/token endpoint with grant_type=refresh_token before making any data requests. Store both the new access_token and the rotated refresh_token.
Exceeding 10 req/sec during paginated fetches. New apps are limited to 5/sec.
Add 150ms delay between paginated requests. Read the Retry-After header and wait that duration. For large monthly reports, run during off-peak hours to preserve the 10,000/day budget.
New orders created while paginating cause the total count to change, potentially causing you to skip or double-count records.
Use a fixed time window (min_created/max_created set before pagination starts) rather than live filters. Store the start/end timestamps once and reuse them throughout the pagination loop.
Etsy stores all monetary values as sub-units: {amount: 2999, divisor: 100} = $29.99. Adding amount values directly without dividing produces 100x inflation.
Always convert with amount/divisor. Implement a toDecimal() helper used on every monetary field. Never sum raw amount values across receipts.
The refresh token is valid for 90 days. If your automation goes unused for 90 days or you fail to store the rotated refresh token after each refresh, you will be locked out.
After every token refresh, save the new refresh_token returned in the response — it rotates each time. Set a calendar alert at 80 days to re-authorize the OAuth flow before expiry.
Rate limits & throttling
Security checklist
- Store ETSY_KEYSTRING and refresh tokens in environment variables or a secrets manager
- Save the rotated refresh token after every OAuth refresh to prevent 90-day expiry lockout
- Use read-only scopes (transactions_r, shops_r) for reporting — never request write scopes for read-only jobs
- Encrypt the refresh token at rest if storing in a database
- Limit Google Sheets API credentials to the specific spreadsheet, not all sheets
- Do not log access tokens or refresh tokens in application logs
- Use service account credentials for Google Sheets access, not personal OAuth tokens
Automation use cases
Daily Revenue Dashboard
Run every morning to fetch yesterday's orders and append a row to a Google Sheet. Track daily trends without opening Etsy.
Monthly Sales Summary for Bookkeeping
First-of-month job fetches all receipts from the prior month, calculates net revenue after tax and shipping, and exports a CSV for accounting or Quickbooks import.
Best-Seller Tracking
Aggregate by listing_id weekly to rank your top products by units sold and revenue. Use the data to decide which listings to restock or promote.
Refund Rate Monitoring
Track was_refunded receipts over time. Alert when refund rate exceeds a threshold (e.g., 5%) to catch quality or shipping issues early.
No-code alternatives
Don't want to write code? These platforms can automate the same workflows visually.
Zapier
Zapier's Etsy integration can trigger on new orders and append rows to Google Sheets. Limited to per-order logging — building daily aggregates requires additional Zapier logic steps.
Make (Integromat)
Make supports scheduled scenarios and the HTTP module for Etsy API calls. Can build paginated receipt fetching + data aggregation + Sheets write in one automated flow.
n8n
Self-hosted n8n can run daily cron workflows that paginate Etsy receipts, aggregate with Code nodes (JavaScript), and write to Sheets or Postgres. Full control with no usage limits.
Best practices
- Always use fixed Unix timestamp ranges (not relative 'last 24 hours') to ensure consistent, reproducible report data
- Store the rotated refresh token after every token refresh — Etsy rotates it and the old one becomes invalid
- Convert all monetary values using amount/divisor before any arithmetic to avoid 100x calculation errors
- Cache listing titles locally (Postgres or Redis) to avoid re-fetching the same listing details on every report run
- Add 150ms delay between paginated requests to stay safely under the 10 req/sec rate limit
- Keep daily and product-level data in separate sheets to simplify filtering and visualization
- Exclude refunded orders (was_refunded=true) from revenue totals for accurate net revenue reporting
- Test with a small date range (single day) before running your first monthly backfill
Ask AI to help
Copy one of these prompts to get a personalized, working implementation.
Help me build a Node.js script that generates daily Etsy sales reports. It should: (1) refresh an OAuth token using a stored refresh token (Etsy tokens expire in 1 hour, refresh tokens in 90 days), (2) fetch all paid receipts from yesterday using GET /shops/{shop_id}/receipts with min_created and max_created Unix timestamps, (3) paginate through all results with 150ms delays, (4) aggregate by listing_id to find top-selling products — remember Etsy uses sub-unit prices (amount/divisor = real price), and (5) write the results to Google Sheets via the Sheets API v4. Include both Authorization: Bearer and x-api-key headers on every Etsy request.
Build me an Etsy sales analytics dashboard that: (1) connects to Etsy using OAuth 2.0 (stored refresh token, auto-refresh on 1-hour expiry), (2) has a date range picker to select reporting period, (3) fetches all paid receipts using GET /shops/{shop_id}/receipts with paginated requests (include both Authorization: Bearer and x-api-key headers), (4) shows total revenue, net revenue (minus tax and shipping), order count, and a bar chart of daily revenue, and (5) has a sortable table of top-selling products by revenue. Use Supabase to cache the report data.
Frequently asked questions
Does the Etsy API provide a dedicated reporting or analytics endpoint?
No. Etsy does not have a dedicated analytics endpoint. You build reports by paginating through GET /shops/{shop_id}/receipts with date filters and aggregating the data yourself. The transactions endpoint provides more granular line-item data if you need SKU-level breakdowns.
How do I convert Etsy API prices to real currency values?
Etsy stores all monetary values as sub-units with a divisor: {amount: 2999, divisor: 100} = $29.99. Always divide amount by divisor before doing any arithmetic. Never sum raw amount values across receipts without this conversion or your totals will be 100x too high.
How far back can I query Etsy receipts?
Etsy does not impose a hard lookback limit on the receipts endpoint. You can use min_created timestamps from years ago. However, very large historical pulls will consume significant API quota — each page of 100 receipts uses one request, so plan accordingly against the 10,000/day limit.
How do I handle refunds in my revenue reports?
Check the was_refunded field on each receipt. Receipts with was_refunded=true should be excluded from revenue totals. Track refunded_count separately to monitor your refund rate over time and flag product quality issues.
My refresh token stopped working after 90 days. How do I prevent this?
Etsy refresh tokens expire in 90 days AND rotate on every use — each refresh call returns a new refresh_token that you must save. If you fail to save the new token after refresh, the next refresh attempt fails. Set a 80-day alert and implement a re-authorization flow to avoid lockouts.
Can I get Etsy sales data into Google Sheets automatically without coding?
Yes — tools like Zapier and Make can write new orders to Sheets automatically. However, building daily aggregates (sum by day, top products) requires additional automation logic. For simple per-order logging, no-code tools work well. For analytical reports, the API-based approach gives you more control.
Can RapidDev help me build a custom Etsy reporting dashboard?
Yes. If you need a custom dashboard combining Etsy sales data with other platforms (Shopify, Amazon, Stripe) or want automated reports delivered to Slack or email, RapidDev can build the full reporting pipeline for you.
Need this automated?
Our team has built 600+ apps with API automations. We can build this for you.
Book a free consultation