The Shopify integration that unifies pixel-tracked revenue with Meta + Google ad spend — and tells you when the pixel is leaking
One Custom App with 12 scopes (read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels — 11 read-only plus the 1 pixel write scope that auto-installs Admaxxer's Web Pixel App Extension), and an optional Custom Pixel manual fallback via Shopify admin > Settings > Customer events for merchants who skip write_pixels. Orders, customers, and checkout events stream into our analytics warehouse — paired with Meta and Google ad data for blended ROAS at the ad level. The 12-scope set unlocks the Shopify-vs-Pixel cross-validation card on /marketing-acquisition with a Match Quality Score that surfaces attribution leakage.
Start 7-day free trial Read the Custom App walkthrough
14-day free trial on every plan. No credit card required. Admaxxer AI Analytics is a marketing analytics platform for ecom and SaaS teams.
What you get
- Two-step setup, full attribution
- Custom App scopes (12 total, alphabetised: read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels) for server-side revenue, Shopify-reported metrics, and the auto-installed Web Pixel App Extension. Custom Pixel manual fallback via Shopify admin > Settings > Customer events for browser-side traffic and UTMs when the auto-install is skipped. Together = source-to-revenue. No theme edits, no script tags, sandboxed by Shopify.
- Order-level attribution
- Every order hitting Shopify is joined to its first-touch ad by source, medium, and campaign. Admaxxer writes the attribution record to our analytics warehouse at order creation and reconciles at checkout_completed.
- Cohort LTV by channel
- 7/30/90-day revenue per acquired customer, drilled to the ad that brought them in. See which Shopify cohorts come back — and which are one-time discount chasers.
- Cross-validation: pixel vs Shopify-reported
- The 12-scope set unlocks the Shopify-vs-Pixel cross-validation card on /marketing-acquisition. Pixel revenue side-by-side with Shopify's own server-side ledger (via read_reports), with delta % and a Match Quality Score (0-100). Surfaces attribution leakage from ad-blockers, Safari ITP, and CSP errors — a differentiator most affordable-tier analytics tools skip.
- Scope-minimal: 11 read-only + 1 pixel
- 12 Custom App scopes total, alphabetised: read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels. 11 are read-only. The pixel scopes (read_pixels, write_pixels) are required so Admaxxer's bundled Web Pixel App Extension can auto-register at OAuth time and capture checkout_completed events from inside Shopify's pixel sandbox — without them, the auto-install fails with ACCESS_DENIED and revenue events go missing.
How it connects (two steps, here's why)
Shopify deliberately splits "what merchants want to expose to a backend integration" from "what merchants want running in their storefront browser." Admaxxer respects that split with two short setups. The Custom App handles server-side data via Shopify's Admin API. The Custom Pixel handles browser events via Shopify's sandboxed Customer Events runtime. Together they give you source-to-revenue attribution AND the Shopify-vs-Pixel cross-validation card.
- Create a Shopify Custom App with 12 scopes (11 read-only + 1 pixel). Go to dev.shopify.com/dashboard > Create app. Enable read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels — 11 read scopes plus the 1 pixel write scope so Admaxxer's Web Pixel App Extension can auto-install. Do NOT add read_analytics (not in Shopify scopes table; HTTP 406) or write_script_tags (deprecated Feb 2025). Release the app, install on your store, and copy the Client ID + Client Secret from Settings > Credentials.
- Paste Client ID + Client Secret into Admaxxer. Paste credentials into Admaxxer Integrations > Shopify (encrypted AES-256-GCM at rest). Click Configure & authorize. Admaxxer can now read orders, products, customers, reports, marketing events, fulfillments, inventory, locations, customer journeys, and discount codes from your shop.
- Install the Admaxxer pixel as a Custom Pixel. In your Shopify admin, go to Settings > Customer events > Add custom pixel. Name it Admaxxer. Paste the snippet shown in Admaxxer's connect form. Set Permission to Not required. Save and Connect/Publish. Pixel fires on next storefront page load.
- Attribution + cross-validation live on first purchase. Custom App ingests data via the canonical 12-scope set (read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels) into our analytics warehouse, and the auto-installed Web Pixel App Extension streams pageviews, UTMs, and checkout events from inside Shopify's pixel sandbox. The moment a customer completes checkout, attribution pairs the order with the first-touch ad — Meta, Google, or organic. Within 24 hours, the cross-validation card on /marketing-acquisition lights up with pixel-vs-Shopify-reported revenue side-by-side and a Match Quality Score.
Data Admaxxer reads
| Dimension | What Admaxxer does with it |
|---|---|
| Orders (read_orders, Custom App) | Order ID, total, line items, customer ID, refund status. Basis for revenue, refunds, AOV, returns, and new-customer revenue tiles in blended MER. |
| Customers (read_customers, Custom App) | Email hash, first order date, order count. Drives the new-vs-returning cohort split and cohort LTV at 7/30/90d. |
| Products (read_products, Custom App) | SKU, title, price. Used for product-level ROAS, creative-to-product matching, and the Top Products card. |
| Reports (read_reports, Custom App) | Shopify's pre-built sales/customer/inventory reports. Powers the Shopify-vs-Pixel cross-validation card on /marketing-acquisition with Match Quality Score. Use read_reports — NOT read_analytics, which is not in Shopify's canonical scopes table and returns HTTP 406. |
| Marketing events (read_marketing_events, Custom App) | Shopify-tagged marketing campaigns. We cross-check them against pixel UTMs to surface attribution gaps when Shopify saw a campaign tag but the pixel didn't. |
| Fulfillments (read_fulfillments, Custom App) | Fulfillment timestamps + refund line items. Powers the lead-time tile, shipped-vs-paid revenue split, and the richer Returns tile. |
| Inventory (read_inventory, Custom App) | InventoryItem.unitCost per SKU. Powers the COGS tile and margin-aware MMM (Shopify Plus only — unitCost is a Plus-tier field). |
| Locations (read_locations, Custom App) | Multi-warehouse split. Powers the per-location stock card and EU-vs-US ad-spend attribution against fulfillment locations (Shopify Plus only). |
| Pageviews + UTMs (Custom Pixel) | URL, title, referrer, anonymous visitor ID, UTM parameters. Streamed via the Custom Pixel installed in Shopify admin > Settings > Customer events. No OAuth scope needed for this step. Powers source attribution, paid-vs-organic split, and landing-page reports. |
| Checkout events (Custom Pixel) | Started / payment-info-submitted / completed — streamed via the Custom Pixel. Stitched to first-touch ad sources via UTMs at checkout_completed. |
| Discount codes (via read_orders) | Applied-code metadata on orders helps separate full-price first orders from discount-chaser cohorts. |
The Custom Pixel snippet (manual install for Online Store 2.0 themes)
Shopify deprecated write_script_tags on Feb 1 2025 and Online Store 2.0 themes silently ignore script_tags injection — the API returns 201 but the script never loads in your storefront. The Custom Pixel is the modern replacement: a small JS snippet that runs in Shopify's sandboxed Web Worker (no DOM access; only analytics.subscribe() and fetch()) and reports pageviews, checkouts, and product views back to Admaxxer at admaxxer.com/api/event. Once you connect the Custom App, the Admaxxer dashboard surfaces the snippet pre-filled with your website_id — copy it, paste it into Shopify Admin → Settings → Customer events → Add custom pixel, click Save and Connect. The pixel fires on the next storefront page load.
The snippet is also available programmatically at GET /api/integrations/shopify/custom-pixel-snippet for any workspace with an active pixel website.
What each event sends
page_viewed→ pageview event withpathandreferrer. Fires on every storefront page including product, collection, cart, and checkout pages.checkout_completed→ payment event withamount_cents(order total in cents, integer),currency(ISO 4217 3-letter code),provider: "shopify",external_payment_id(Shopify order GID), andemail(hashed server-side before storage). Powers Net Revenue, True AOV, and Total Sales tiles.product_viewed→ custom event withgoal_name: "product_viewed"andmetadata.product_id. Powers Top Products and product-level ROAS reports.
Every payload is validated server-side against Admaxxer's canonical pixel event schema. Malformed events are rejected at /api/event; only schema-valid events flow into our analytics warehouse.
Safety and security
- Client secrets encrypted AES-256-GCM at rest. Never logged, never printed in error traces.
- Revocable from your Shopify admin at any time — uninstall the Custom App and access stops instantly. Disabling the Custom Pixel from Settings > Customer events stops browser events independently.
- Scope-minimal Custom App: 12 scopes alphabetised (read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels). 11 are read-only; write_pixels is the single narrow write scope, used solely to register our bundled Web Pixel App Extension via Shopify's webPixelCreate mutation. Admaxxer's Custom App never has the ability to modify orders, customers, products, themes, or billing.
- No deprecated scopes: we never request write_script_tags (deprecated Feb 1, 2025) or read_analytics (not in Shopify's canonical access-scopes table; HTTP 406 even when enabled).
- Strict rate-limit respect. Admaxxer queues Shopify API reads and never bursts past documented limits.
Frequently asked
- Why am I seeing 'Contains invalid scopes' on dev.shopify.com?
- Most common cause is a copy-paste typo. The two scope names that historically trigger this are write_script_tags (deprecated by Shopify on February 1, 2025; script tags expire Aug 26, 2026 for non-Plus stores) and read_analytics (NOT in Shopify's canonical access-scopes table at shopify.dev/docs/api/usage/access-scopes; returns HTTP 406 even when enabled). The Custom App's canonical 12-scope set is read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels — 11 read-only scopes plus the 1 pixel write scope that lets Admaxxer's Web Pixel App Extension auto-install. Use read_reports for analytics access; never read_analytics.
- Do I need to publish on the Shopify App Store?
- No. The default Admaxxer Shopify flow uses Shopify Custom Apps, which live inside your admin — no App Store listing, no review queue. You create the app, paste credentials, then install our pixel as a Custom Pixel via Shopify admin > Settings > Customer events.
- What scopes does the Custom App need?
- 12 scopes total — alphabetised: read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels. 11 read-only: read_orders (revenue, refunds, AOV, returns — also gates Order.customerJourneySummary, the Shopify first-touch / last-touch attribution per order powering the Sources & Attribution lens, per Shopify's GraphQL reference; see GL#420), read_products (titles for line items), read_customers (new-vs-returning cohort), read_discounts (promo-code attribution + discount-driven revenue breakdown on /marketing-acquisition), read_reports (Shopify-reported revenue for cross-validation), read_marketing_events (Shopify-tagged campaigns vs pixel UTMs), read_fulfillments (lead time + refund line items), read_inventory (unit cost / COGS, Plus only), read_locations (multi-warehouse split, Plus only), and read_pixels (audit which pixels are installed on your store). Plus the 1 write scope: write_pixels (register Admaxxer's Web Pixel App Extension at OAuth time so checkout_completed events flow into your dashboard within seconds). If you skip write_pixels, the auto-install fails with ACCESS_DENIED and you'll need to paste the Custom Pixel snippet manually via Shopify admin > Settings > Customer events as the fallback.
- What's the difference between read_reports and read_analytics?
- read_reports is the canonical 2026 scope listed in Shopify's access-scopes documentation at shopify.dev/docs/api/usage/access-scopes. Description: 'Analytics and reporting data through the shopifyqlQuery query.' It's the scope you want for any analytics / cross-validation work. read_analytics is NOT in Shopify's canonical access-scopes table — it appears to be a legacy / Plus-only ShopifyQL gate that Shopify quietly retired. Even when 'enabled,' API calls return HTTP 406 (community thread: shopifyql-analytics-api-returns-406-on-valid-request-plus-store-read-analytics-enabled/416853), and some dev dashboards reject it at config time with 'Contains invalid scopes.' Admaxxer deliberately uses read_reports and never requests read_analytics.
- How does cross-validation work?
- Pixel events tell us what visitors did (browser-side); Shopify's read_reports API tells us what actually happened in the merchant of record's ledger (server-side). Admaxxer pulls both into our analytics warehouse via a daily Shopify reports sync and renders an automated attribution-quality check on /marketing-acquisition: pixel revenue vs Shopify-reported revenue side-by-side, the delta in dollars and percent, and a Match Quality Score (0-100). 95+ means your pixel is healthy; below 80 means ad-blockers, Safari ITP, or CSP errors are eating measurable revenue — a differentiator most affordable-tier analytics tools skip on the same scope set.
- Why two steps (Custom App + Custom Pixel)?
- Shopify scopes give us revenue (server-side, via the Admin API). Custom Pixels give us traffic (browser-side, via Shopify's sandboxed Customer Events runtime). Both are needed for source-to-revenue attribution — the Custom App can't see UTMs or pageviews, and the Custom Pixel can't see refunds or full order economics. Doing them as two separate steps keeps the Custom App fully read-only and decouples pixel install from app install.
- Why does the Custom App now request write_pixels?
- Updated 2026-05-01 (GL#326): the Custom App now requests the full canonical 12-scope set (read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels) so Admaxxer's bundled Web Pixel App Extension can auto-install at OAuth time. Without write_pixels, webPixelCreate returns ACCESS_DENIED and checkout_completed events never reach your dashboard — the +100% Shopify revenue gap that surfaced in production on 2026-04-30. write_pixels does NOT grant write access to orders, customers, products, inventory, or any other resource; it only registers the bundled Web Pixel App Extension. Merchants who prefer zero write scopes can decline write_pixels and paste the Custom Pixel snippet manually via Shopify admin > Settings > Customer events.
- Do I need to give Admaxxer access to write any data?
- Just one narrow write scope. The Custom App's full 12-scope set (read_customers, read_customer_events, read_discounts, read_fulfillments, read_inventory, read_locations, read_marketing_events, read_orders, read_pixels, read_products, read_reports, write_pixels) is 11 read-only scopes plus write_pixels. write_pixels only registers Admaxxer's Web Pixel App Extension on your store via Shopify's webPixelCreate mutation so we can capture checkout_completed events from inside Shopify's pixel sandbox; it does NOT grant write access to orders, customers, products, inventory, locations, or any other resource. If you'd rather skip write_pixels entirely, install the pixel manually via Shopify admin > Settings > Customer events (no OAuth scope needed for the manual path).
- Does the Custom Pixel fire on checkout?
- Yes. Shopify's Custom Pixel runtime exposes the full standard customer-events API — page_viewed, product_viewed, product_added_to_cart, checkout_started, payment_info_submitted, checkout_completed — on every Shopify plan tier including Plus and Checkout Extensibility. The pixel runs in a sandboxed worker honoring Shopify's consent banner.
- Is Shopify Plus supported?
- Yes. Shopify Plus stores work with the same Custom App + Custom Pixel flow. read_inventory and read_locations specifically unlock Plus-only fields (unitCost for margin-aware MMM and per-location stock for multi-warehouse attribution). Checkout Extensibility, Launchpad, and Flow-driven webhooks are all compatible.
- Can I backfill historical orders?
- On connect, Admaxxer pulls recent orders via the Shopify Admin GraphQL API. The default read_orders scope returns orders from approximately the last 60 days; deeper history requires Shopify's read_all_orders scope, which we deliberately don't request to keep the install scope-minimal. Going forward, every new order is captured via webhooks (orders/create, orders/paid, refunds/create) so you'll have complete coverage from the day you connect.
Connect Shopify in two short steps
14-day free trial on every plan. No credit card required.