Audience: This guide is for developers and technical teams who need to add UTM attribution data to Shopify orders—either backfilling historical orders or capturing UTMs for future orders.
Overview
SourceMedium extracts UTM attribution data from Shopify order-levelcustomAttributes. This guide covers two scenarios:
- Backfilling existing orders — You have attribution data (from spreadsheets, surveys, external tools) and want to write it to historical orders.
- Capturing UTMs going forward — You want to automatically capture UTM parameters at checkout for future orders.
Backfill Historical Orders
Use the Shopify Admin API to add attribution data to existing orders
Capture Future UTMs
Use Checkout UI Extensions to automatically capture UTMs at checkout
Supported Keys (Normalized)
SourceMedium extracts a specific allowlist of keys from order-levelcustomAttributes.
Keys are normalized before matching (snake_case / camelCase / delimiter / case agnostic):
utm_source,utmSource,UTM_SOURCE,utm-source→ treated as the same keysm_utmParams,smUtmParams→ treated as the same keyGE_utmParams,ge_utm_params→ treated as the same key
To reduce collisions with other checkout apps, prefer the
sm_utm_* / sm_utmParams keys for explicit overrides. Standard utm_* keys are also supported.| Key | Description | Example |
|---|---|---|
sm_utm_source, sm_utm_medium, sm_utm_campaign, sm_utm_content, sm_utm_term, sm_utm_id | SourceMedium override UTMs (recommended) | sm_utm_source=facebook |
utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_id | Standard UTMs | utm_campaign=summer_sale_2025 |
sm_utmParams, utmParams, GE_utmParams | Aggregate UTM query string (parsed) | utm_source=google&utm_medium=cpc |
sm_referrer, referrer | Referring URL | https://blog.example.com/review |
Click IDs (fallback inference)
Click IDs are processed but not stored as raw values. If no explicitutm_source is present, their presence infers a channel-level utm_source (fallback-only).
| Click ID | Inferred utm_source |
|---|---|
scclid | snapchat |
irclickid | impact |
msclkid | microsoft |
ttclid | tiktok |
fbclid | meta |
gclid | google |
scclid > irclickid > msclkid > ttclid > fbclid > gclid.
Conflict resolution (deterministic)
If you provide conflicting values (e.g., bothsm_utm_source and utm_source, or both direct keys and utmParams), SourceMedium resolves each final field with a deterministic waterfall:
- UTM fields: direct
sm_utm_*→ directutm_*→ parsed fromsm_utmParams→ parsed fromutmParams→ parsed fromGE_utmParams utm_sourceonly: if still missing, infer from click IDs (scclid→irclickid→msclkid→ttclid→fbclid→gclid)- Referrer:
sm_referrer→referrer
utm_source and UTM_SOURCE), SourceMedium de-dupes deterministically using MAX() (lexicographically largest value). To avoid surprises, only set each key once.
Backfilling Historical Orders
If you have attribution data for existing orders (e.g., from post-purchase surveys, manual tracking, or external tools), you can write it to Shopify orders so SourceMedium can extract it.How It Works
Available Methods
| Method | Best For | Technical Skill Required |
|---|---|---|
| Shopify Flow | Small batches, no-code users, Shopify Plus | Low (no coding) |
| Admin API Script | Large bulk backfills, automation | Medium (Python/Node.js) |
| Third-Party Apps | Limited - most don’t support order attributes | Varies |
No CSV import available: Unlike products, Shopify does not support CSV import for order attributes. Matrixify and similar bulk import tools also do not support
customAttributes on orders.Option 1: Shopify Flow (No-Code)
If you have Shopify Plus, you can use Shopify Flow with the “Send Admin API request” action. This is ideal for smaller batches or when you want to trigger updates based on conditions.Create a Flow workflow
Go to Settings → Flow and create a new workflow. Use a trigger like “Order created” for new orders, or tag orders you want to backfill and trigger on “Order tags added”.
Option 2: Admin API Script (Bulk)
For large backfills (hundreds or thousands of orders), use a script with the Shopify Admin GraphQL API.Prerequisites
Shopify Admin API access with
write_orders scopeOrder IDs mapped to your attribution data
Attribution data in the supported key format (see table above)
Implementation
- GraphQL Mutation
- Python Script
- Node.js Script
Important Considerations
Merging vs Overwriting Attributes
Merging vs Overwriting Attributes
The
orderUpdate mutation replaces all customAttributes on the order. If the order already has attributes you want to keep:- First, fetch existing attributes via
orderquery - Merge your new attributes with existing ones
- Send the combined array in the mutation
Rate Limits
Rate Limits
Shopify’s Admin API has rate limits. For bulk backfills:
- Use the Bulk Operations API for large datasets
- Or throttle requests to ~2 per second for standard API calls
- Consider batching updates overnight
Order Age Limits
Order Age Limits
Shopify allows updating orders regardless of age, but consider:
- Very old orders may already have SourceMedium attribution from other sources
- Order-level
customAttributesare treated as an explicit override (see Attribution Source Hierarchy)
Verification
After backfilling:- Verify in Shopify Admin: Orders → [Order] → Additional details should show your attributes
- Wait for sync: SourceMedium syncs typically run every 24 hours
- Check Orders Deep Dive: Verify the attribution appears in SourceMedium dashboards
Capturing UTMs for Future Orders
To automatically capture UTM parameters at checkout for new orders, use a Shopify Checkout UI Extension.This approach supplements your existing tracking (GA4, Elevar). It’s particularly useful when cookie-based tracking fails due to ad blockers or cross-domain issues.
How It Works
Prerequisites
Shopify Plus or ability to create Checkout UI Extensions
Access to deploy changes to your Shopify theme/app
Method to write cart attributes before checkout (theme JS / Storefront API)
Step 1: Write Attribution to Cart Attributes (Before Checkout)
Checkout UI Extensions are sandboxed and can’t directly access the browser DOM (e.g.,document.cookie, localStorage, or window.location). To make UTMs available at checkout, capture them on the storefront and write them into cart attributes before the buyer starts checkout.
This example uses the Online Store cart/update endpoint to set SourceMedium override keys (sm_utm_*). These cart attributes flow into checkout attributes and appear on the order as customAttributes.
If you’re using a headless storefront, use the Storefront API to set cart attributes instead of
cart/update.js.Step 2: Create Checkout UI Extension
Step 3: Configure and Deploy
Limitations
Troubleshooting
Attributes appear in Shopify but not SourceMedium
Attributes appear in Shopify but not SourceMedium
- Unsupported key: Only allowlisted keys are extracted (see “Supported Keys”)
- Sync timing: Wait 24-48 hours for data to flow through
- Connector version: Ensure your Shopify connector supports
customAttributes(contact support to verify)
Backfill script failing with permission errors
Backfill script failing with permission errors
Ensure your API credentials have
write_orders scope. For private apps, this must be enabled in the app settings.Existing attributes being overwritten
Existing attributes being overwritten
The
orderUpdate mutation replaces all attributes. Fetch existing attributes first, merge, then update.Related Resources
Shopify Admin API - Order Update
Official documentation for the orderUpdate mutation
Shopify Checkout Attributes API
Documentation for useApplyAttributeChange hook
UTM Setup
What UTMs are, what each value means, and how to tag links
Attribution Source Hierarchy
How SourceMedium prioritizes attribution from multiple sources
FAQ
Which method should I use?
Which method should I use?
- Backfill: You have historical attribution data you want to add to existing orders
- Capture going forward: You want to automatically capture UTMs for new orders
- Both: Most brands benefit from backfilling historical data AND capturing future UTMs
What's the priority if multiple sources have UTMs?
What's the priority if multiple sources have UTMs?
SourceMedium uses an attribution source hierarchy. If allowlisted attribution is present in order
customAttributes, it is treated as an explicit override and takes top priority.Can I backfill orders that already have attribution in SourceMedium?
Can I backfill orders that already have attribution in SourceMedium?
Yes. If you write allowlisted attribution to order
customAttributes, it is treated as an explicit override and will replace the order’s last-touch attribution (unless you only set a subset of fields, in which case missing fields may be filled from lower-priority sources when the channel matches).How do I know if my connector supports this?
How do I know if my connector supports this?
SourceMedium’s latest Shopify connector extracts
customAttributes automatically. Contact support if you’re unsure whether your connector supports this feature.
