Numeric goals (metric targets) like "$50K in total sales this quarter" can now be created, retrieved, updated, and deleted from your app using four new operations. You can work with the same targets merchants see in the admin, through the same API, the same rules, and the same validation.
Setting targets and checking progress happened entirely within Analytics in the Shopify admin. External goal-setting tools and BI tools couldn't touch them.
Apps can read and write targets, and targets created by an app appear on admin and dashboard gauges alongside those created by merchants.
analyticsTargetCreateCreate one by specifying a metric, target value, period, and an optional filter (e.g., limited to a specific sales channel or product).
analyticsTargetsRetrieve a shop's targets. Supports pagination.
analyticsTargetUpdateLets you change the metric, name, target value, period, and filter.
analyticsTargetsDeleteDelete a target.A deleted target cannot be restored.
analyticsTargetsDelete uses a plural name (targets). Since deletion is irreversible, it's safest to add a confirmation step in the UI.| Item | Details |
|---|---|
| Scope | read_reports and write_reports permissions are required. |
| Deduplication | A target is uniquely identified by the combination of metric, period (date range), and filter. If you attempt to create a duplicate, you get back a userError that guides you to the necessary changes. |
| Status calculation | From the period at query time and the current metric value, thestatus field (In progress / Achieved / Not achieved / Upcoming) is automatically derived by the API. |
| Filter | Each target can have, in its ShopifyQL WHERE clause, one dimension-based filter. The operator is = or IN. |
status is not a stored value; it's derived each time from the "period" at query time and the "current metric value." Your app doesn't need to compute or store the status itself.
In API version 2026-04 ,ShopifyqlTableDataColumn 's ColumnDataType now has two new values added. Previously, FLOAT was the value returned by the affected metrics.Callers using a version earlier than 2026-04 are unaffected.
UNITLESS_SCALARA dimensionless score value with no unit. Applied to web performance metrics: p50_cls / p75_cls / p90_cls / p99_cls(the Cumulative Layout Shift percentile).
MULTIPLIERA value representing a ratio or multiplier (e.g., 3.2x).shop_campaign_return_on_ad_spend(return on ad spend / ROAS) is where it applies.
FLOAT will, when upgrading to 2026-04, need to add handling for UNITLESS_SCALAR / MULTIPLIER . Also review the display format ("3.2x", etc.) at the same time.Even for reads, read_reportsis required; for create, update, and delete, write_reports is required. Be sure to include them in your app's access scope request.
Duplicates are detected by "metric × period × filter." Creating an already-existing key userError. Design your sync as "create if missing, update if present" and it won't collide.
In progress / Achieved / Not achieved / Upcoming are derived automatically at query time. Don't compute or store them yourself. They switch over naturally as the period or values change.
ShopifyQL's WHERE can hold only one dimension filter. ANDing multiple conditions isn't allowed. For per-sales-channel or per-product targets, create separate targets.
Targets your app creates also appear in the Targets list and dashboard with the same gauge, and merchants can edit or delete them directly.Assume they may be overwritten from outside your app, so design your sync to be idempotent and able to detect diffs.analyticsTargets supports pagination, so you can scan every record.
analyticsTargetCreate auto-generates smart initial goals, suggesting the period and metrics together.analyticsTargetUpdate and avoiduserError .analyticsTargets lets you read the merchant's goals and overlay progress and achievement onto your own charts.status is auto-derived by the API, so use it as-is instead of computing it yourself. For stores with many records, fetch them all with pagination.analyticsTargets is fetched across stores, surfacing a consolidated view of the stores that are Not achieved.read_reports / write_reports granted; since deletion is irreversible, a cross-store bulk analyticsTargetsDelete must require a confirmation flow.