Hey everyone,
I’ve been experimenting with the GraphQL Admin API, specifically using ShopifyQL to pull custom reporting on customer spend. I noticed that if you filter the sales dataset by a specific customer’s email using a WHERE clause, you can successfully pull their time-bound order data (using SINCE and UNTIL).
It works perfectly in my testing, but before I build too much logic around this, I’m hoping to get some real-world feedback from anyone who uses this in production.
A few things I’m trying to figure out:
-
Latency: How long does it typically take for a brand-new order to actually reflect in the sales dataset? Are we looking at seconds or minutes?
-
Gross vs. Net: The total_sales metric pulls the gross amount (with shipping/taxes). Has anyone figured out a clean way to isolate just the net product revenue with this query?
-
Refunds: If an order happens inside my queried date range, but the refund is processed weeks later outside of that range, does the total_sales still decrement correctly?
Also, since this is an on-the-fly analytical query, I’m a bit worried about rate limits or other undocumented gotchas. If anyone has had a bad experience relying on this API at scale, I’d love to hear your war stories so I can avoid the same traps!
Thanks in advance for the help.
Good questions, and smart to get clarity before building production logic on top of this!
For net product revenue, you’ll want to swap total_sales for net_sales. The formula behind it is gross_sales - discounts - returns, so it strips out discounts and returns without including shipping, taxes, duties, or fees. total_sales is the full customer-facing amount (net sales + shipping + taxes + fees + duties), which is why it looks inflated for revenue analysis.
Reversals are recorded at the time the refund is processed, not backdated to the original order date. So if an order is placed January 15th and refunded March 10th, a query with SINCE 2026-01-01 UNTIL 2026-01-31 will still show the original sale amount. The reversal shows up in March’s data instead. If you need a complete net picture for a given window, you’d either need to widen your date range to capture later reversals or separately query returns for the period after your window. The net_sales metric handles the math for whatever date range you query, but it can only factor in reversals that fall within that range.
Data freshness has no documented SLA on how quickly a new order appears in the sales dataset via the 3P API. It’s not real-time. In practice, expect a pipeline delay (likely minutes, not seconds), but Shopify doesn’t publish a specific number. I’d recommend not building time-sensitive logic that depends on sub-minute freshness from this endpoint.
Rate limits for shopifyqlQuery are separate from the standard GraphQL cost bucket. They’re complexity-based, factoring in the number of metrics in your SHOW clause, dimensions in GROUP BY, and overall clause count. If you hit the limit, you get a 429 with a 60-second reset timer. Best practice is to keep your date ranges narrow, limit dimensions, and implement exponential backoff on 429 responses.