AgentStack
SKILL verified MIT Self-run

Shopify Admin Order Attribution Report

skill-40rty-ai-shopify-admin-skills-shopify-admin-order-attribution-report · by 40RTY-ai

Read-only: parses UTM source/medium/campaign from order landing site URLs to attribute revenue, AOV, and conversion volume to marketing channels.

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-40rty-ai-shopify-admin-skills-shopify-admin-order-attribution-report

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
Are you the author of Shopify Admin Order Attribution Report? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.

About

Purpose

Pulls recent orders, extracts the UTM parameters embedded in each order's landingPageUrl query string, and rolls up revenue, order count, and average order value (AOV) by utm_source, utm_medium, and utm_campaign. Builds a marketing attribution report directly from first-party Shopify order data — no external analytics tool required. Read-only — no mutations.

Prerequisites

  • Authenticated Shopify CLI session: shopify store auth --store --scopes read_orders
  • API scopes: read_orders

Parameters

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | store | string | yes | — | Store domain (e.g., mystore.myshopify.com) | | daysback | integer | no | 30 | Lookback window for orders to attribute | | groupby | string | no | source | Primary grouping dimension: source, medium, campaign, or source_medium | | minorders | integer | no | 1 | Minimum orders per group to include in the report | | includeorganic | bool | no | true | When false, omit orders with no UTM parameters from the breakdown | | format | string | no | human | Output format: human or json |

Safety

> ℹ️ Read-only skill — no mutations are executed. Safe to run at any time. Attribution accuracy depends on whether the storefront propagates UTM parameters into the checkout — orders that bypass the storefront (POS, draft orders, subscriptions) will not have landing site URLs.

Workflow Steps

  1. OPERATION: orders — query

Inputs: query: "created_at:>='' financial_status:paid", first: 250, select landingPageUrl, referrerUrl, customerJourneySummary, totalPriceSet, pagination cursor Expected output: All paid orders in the window with landing page URLs; paginate until hasNextPage: false

  1. For each order, parse landingPageUrl query string and extract utm_source, utm_medium, utm_campaign, utm_term, utm_content. Orders without UTM params are bucketed as (direct/organic) if include_organic: true.
  1. Aggregate by the group_by dimension: sum order count, sum revenue (in shop currency), compute AOV = revenue / orders.
  1. Sort groups by revenue descending; filter out groups below min_orders.

GraphQL Operations

# orders:query — validated against api_version 2025-01
query OrdersWithAttribution($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        createdAt
        landingPageUrl
        referrerUrl
        displayFinancialStatus
        totalPriceSet {
          shopMoney {
            amount
            currencyCode
          }
        }
        customerJourneySummary {
          firstVisit {
            landingPage
            source
            sourceType
            referrerUrl
            utmParameters {
              source
              medium
              campaign
              term
              content
            }
          }
          lastVisit {
            landingPage
            source
            sourceType
            utmParameters {
              source
              medium
              campaign
            }
          }
          momentsCount
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Session Tracking

Claude MUST emit the following output at each stage. This is mandatory.

On start, emit:

╔══════════════════════════════════════════════╗
║  SKILL: Order Attribution Report             ║
║  Store:                        ║
║  Started:              ║
╚══════════════════════════════════════════════╝

After each step, emit:

[N/TOTAL]   
          → Params: 
          → Result: 

On completion, emit:

For format: human (default):

══════════════════════════════════════════════
ORDER ATTRIBUTION REPORT  ( days)
  Orders attributed:   
  Total revenue:       $
  Untagged (direct):     (%)

  Top sources by revenue:
         Orders:    Revenue: $   AOV: $
         Orders:    Revenue: $   AOV: $
  Output: attribution_report_.csv
══════════════════════════════════════════════

For format: json, emit:

{
  "skill": "order-attribution-report",
  "store": "",
  "period_days": 30,
  "group_by": "source",
  "orders_attributed": 0,
  "total_revenue": 0,
  "currency": "USD",
  "groups": [
    { "key": "google", "orders": 0, "revenue": 0, "aov": 0 }
  ],
  "output_file": "attribution_report_.csv"
}

Output Format

CSV file attribution_report_.csv with columns: group_key, utm_source, utm_medium, utm_campaign, orders, revenue, aov, currency, pct_of_revenue

Error Handling

| Error | Cause | Recovery | |-------|-------|----------| | THROTTLED | API rate limit exceeded | Wait 2 seconds, retry up to 3 times | | landingPageUrl is null | Order placed via POS, draft, or subscription | Bucket as (direct/organic), count separately | | Malformed query string | Manual or partial UTM tagging | Skip parse failure, treat as direct, log count | | customerJourneySummary access denied | Store on plan that does not expose this field | Fall back to landingPageUrl parsing only |

Best Practices

  • Use group_by: source_medium to distinguish paid traffic (google/cpc) from organic (google/organic).
  • A high (direct/organic) percentage usually means UTM tagging is missing on paid campaigns — fix the campaign URLs, not the report.
  • Run weekly during active campaigns to track attribution drift; run monthly for steady-state reporting.
  • Cross-reference revenue here with ad spend from your ad platforms to compute true ROAS — this skill provides the order-side numerator only.
  • For multi-touch attribution, also surface customerJourneySummary.firstVisit vs lastVisit to compare first-click vs last-click models.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.