Skip to main content
RapidDev - Software Development Agency

How to Automate Etsy Sales Reports Using the API

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.

Need help automating? Talk to an expert
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate5 min read45–60 minutesEtsyLast updated May 2026RapidDev Engineering Team
TL;DR

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.

Quick facts about this guide
FactValue
PlatformEtsy
Auth methodOAuth 2.0 with mandatory PKCE
Rate limits10 req/sec, 10,000 req/day (new apps: 5/sec, 5,000/day)
DifficultyIntermediate
Time required45–60 minutes
Last updatedMay 2026

API Quick Reference

Auth

OAuth 2.0 with mandatory PKCE

Rate limit

10 req/sec, 10,000 req/day (new apps: 5/sec, 5,000/day)

Format

JSON

SDK

REST only

API overview

Base URLhttps://openapi.etsy.com/v3/application

Authentication

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

GET/shops/{shop_id}/receipts

Returns 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.

ParameterTypeRequiredDescription
optional
optional
optional
optional
optional
optional
GET/shops/{shop_id}/transactions

Returns individual transactions (line items) with listing, quantity, price, and buyer info. More granular than receipts for product-level reporting.

ParameterTypeRequiredDescription
optional
optional
optional
GET/shops/{shop_id}/receipts/{receipt_id}

Fetches a single receipt with full detail. Useful for reconciling a specific order in your reporting pipeline.

ParameterTypeRequiredDescription
optional
optional
GET/listings/{listing_id}

Returns listing details including title, tags, and taxonomy. Use to enrich transaction data with product category for category-level reporting.

ParameterTypeRequiredDescription
optional

Step-by-step automation

1

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.

request.sh
1# Refresh the access token
2curl -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"
5
6# Test with a simple shops/me call
7curl -X GET https://openapi.etsy.com/v3/application/users/me \
8 -H "Authorization: Bearer $ETSY_ACCESS_TOKEN" \
9 -H "x-api-key: $ETSY_KEYSTRING"
2

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).

request.sh
1# Get receipts for a specific day (Unix timestamps)
2# May 22, 2026 00:00:00 UTC = 1748044800
3# May 22, 2026 23:59:59 UTC = 1748131199
4curl -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"
3

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.

request.sh
1# No direct curl equivalent aggregation is done in code after fetching data
4

Export 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.

request.sh
1# Write to a Google Sheets range via Sheets API v4
2curl -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

Cause

Access token expired (1-hour TTL) or both required headers not included. Etsy requires Authorization: Bearer AND x-api-key on every request.

Fix

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.

Cause

Exceeding 10 req/sec during paginated fetches. New apps are limited to 5/sec.

Fix

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.

Cause

New orders created while paginating cause the total count to change, potentially causing you to skip or double-count records.

Fix

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.

Cause

Etsy stores all monetary values as sub-units: {amount: 2999, divisor: 100} = $29.99. Adding amount values directly without dividing produces 100x inflation.

Fix

Always convert with amount/divisor. Implement a toDecimal() helper used on every monetary field. Never sum raw amount values across receipts.

Cause

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.

Fix

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.

Pros
    Cons

      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.

      Pros
        Cons

          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.

          Pros
            Cons

              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.

              ChatGPT / Claude Prompt

              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.

              Lovable / V0 Prompt

              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.

              RapidDev

              Need this automated?

              Our team has built 600+ apps with API automations. We can build this for you.

              Book a free consultation
              Matt Graham

              Written by

              Matt Graham · CEO & Founder, RapidDev

              1,000+ client projects delivered. Columbia University & Harvard Business School alumnus, U.S. Navy veteran. About the author →

              Want this built for you?

              We ship production apps at a fixed price — $13K–$25K, 6–10 weeks, source code yours. You've seen what it takes; we do it every week.

              Get a fixed-price quote

              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.