Skip to main content
Version 2026-10. This page defines every value of shop stats: GET /v1/workspace/stats, and get_my_shop_stats in an AI assistant. They are your shop’s real finances, not estimates. They need the Financial reports permission in the workspace.

Where the numbers come from

Shop stats come from your Etsy payment account’s ledger: the entries Etsy books for sales, refunds, fees, ads and payouts. Each sync stores the ledger as one row per shop and UTC day, the same daily figures the Alura app’s financial reports use. The API adds up those days and never calls Etsy.
  • Grain. UTC days. A week starts on Monday.
  • Units and reviews come from your orders and reviews, stored on the same daily rows.
  • Signs. The ledger books costs as negative amounts. The API turns them around: every cost, fee and refund is a positive number.
  • Money is plain numbers in currency, rounded to 2 decimals. Shares are fractions with 4 decimals.

The default values

A share is null when what it divides by is 0 or unknown. It’s never 0 for that reason.

More detail with expand

expand= (on MCP, include) adds groups. Together they cover all 41 metrics of the Alura app’s financial reports. Adding up. Money and counts are summed over the days. Shares are worked out again from the sums, never averaged across days. closing is the last day’s balance, not a sum. Across several shops, everything is summed, closing balances included.

Your own costs

Costs you enter in Alura (the Costs page) are your own costs, such as materials. They count only on days that have ledger data.
  • When you entered costs, fees.your_costs holds them, and they’re included in costs.total and profit.net.
  • When you didn’t, fees.your_costs is null, costs.total and profit.net hold Etsy’s costs only, and a your_costs_missing notice names the shops. profit.net_before_your_costs then gives revenue minus Etsy’s costs.
A shop counts as having entered costs if it ever has. With several shops, a shop without costs adds nothing to your_costs, and your_costs_missing names it.

Currency

The ledger is in the payment account’s currency. That can differ from the currency your listings show: some shops price in US dollars and are paid in another currency.
  • Per shop, Alura reads the ledger’s currency from its entries. When it can’t tell, the currency is unknown.
  • The default currency is the shops’ common currency. When the shops use different currencies, it’s US dollars. Ask for another with currency=; a code Alura has no exchange rate for is 422 unprocessable.
  • Converting. When anything was converted, the response has conversion (from, to, rate_date, method: "current_rate") and a currency_converted_at_current_rate notice. History is converted at the rates of rate_date, not each day’s rate. conversion is null when nothing was converted. Counts are never converted.
  • An unknown currency. A single shop with an unknown currency gets currency: null. Mixed with other shops, its money can’t be added up, so the call fails with 422 unprocessable. Ask for that shop alone with shop_id, or add group_by=shop. With group_by=shop, the totals leave that shop out, by_shop shows it with currency: null, and a currency_unknown notice names it.

Ranges, intervals and comparing

  • Range. period is 7d, 30d (the default), 90d or 365d, ending on the last day covered for every included shop. Or give from and to, both included.
  • interval is day, week, month, quarter or year, at most 366 points, and adds series.
  • compare=previous_period adds compare, the same values for the period of the same length just before, and change: for each value, (this period minus the previous) divided by the absolute value of the previous, so a loss that shrinks from −100 to −50 reads +0.5. change is null when either value is unknown or the previous is 0.
  • group_by=shop adds by_shop, each shop’s own values in the response currency.
  • Over MCP (get_my_shop_stats), so an answer stays within an AI client’s budget: at most 18 series points, group_by=shop over at most 16 shops (pass shop_id for more), and not interval and group_by together. A call past a limit is a 400 invalid_request that suggests a coarser interval or a shorter range. REST keeps the 366 points and every shop.

Missing days are never 0

Each shop has a coverage window in coverage: from is its first day with ledger data, and through is the day before the latest sync that stored both its ledger and its daily figures. A day Alura doesn’t know is left out of the totals, and a notice names it. It’s never counted as a day with no sales. A point of series with no data at all is null in every value. closing is null when the last day of its range or point has no data.

Known limits

  • Quiet days look unknown. A day with no ledger entries has no row, so a shop with few sales shows null days and no_financials_row notices.
  • Some days may hold zeros. Until a fix to Alura’s ledger sync (late 2026), a failed ledger read could still store a day’s figures, with zeros for the entries it missed. Alura can’t tell those zeros from real ones, so stats serve them as data. The fix stops new ones.

Why listing revenue won’t match

The revenue here won’t equal the sum of your listings’ period revenue for the same days, because the two come from different sources. Listing numbers come from orders: item price minus item discounts, in the orders’ currency, on the day each order was placed, with refunds kept apart. Shop stats revenue comes from the payment ledger: after refunds and the taxes Etsy collects, in the payment account’s currency, on the ledger’s own dates. Each also has its own coverage. See Listing stats.

Version history