
Shopify Admin Vip Customer Identifier
- 2 installs
- 173 repo stars
- Updated June 26, 2026
- 40rty-ai/shopify-admin-skills
shopify-admin-vip-customer-identifier is a Claude Code skill that identifies top-spending Shopify customers and optionally tags qualified customers as VIPs.
About
A Claude Code skill that ranks Shopify customers by lifetime spend and order frequency, identifies the top percentile as VIP candidates, and exports the list. It can optionally apply a VIP tag via customerUpdate, defaulting to dry-run. Marketers use it to build loyalty segments and prioritize white-glove support.
- Ranks customers by lifetime spend, order frequency, or a composite score
- Identifies the top N% as VIP candidates and exports a list
- Optionally tags qualified customers via customerUpdate; dry-run by default
Shopify Admin Vip Customer Identifier by the numbers
- 2 all-time installs (skills.sh)
- Ranked #729 of 853 Sales & Marketing skills by installs in the Skillselion catalog
- Data as of Aug 1, 2026 (Skillselion catalog sync)
shopify-admin-vip-customer-identifier capabilities & compatibility
Free; requires an authenticated Shopify CLI session with read_customers and read_orders.
- Capabilities
- customer segmentation · vip tagging · lifetime value ranking
- Use cases
- marketing · data analysis
- Runs
- Runs locally
- Pricing
- Free
What shopify-admin-vip-customer-identifier says it does
Identifies top-spending customers (top N% by lifetime value or order frequency) and exports a VIP candidate list; optionally tags qualified customers as VIPs.
Used to build loyalty segments, prioritize white-glove support, or seed exclusive-access campaigns.
npx skills add https://github.com/40rty-ai/shopify-admin-skills --skill shopify-admin-vip-customer-identifierAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 173 |
| Last updated | June 26, 2026 |
| Repository | 40rty-ai/shopify-admin-skills ↗ |
What it does
Identify top-spending Shopify customers as VIP segments and optionally tag them.
Who is it for?
Marketers building loyalty segments or exclusive-access campaigns from Shopify data.
Skip if: External CRM segmentation; it uses Shopify customer aggregates only.
When should I use this skill?
You want to build a VIP loyalty segment from lifetime value or order frequency.
What you get
A ranked VIP candidate list, with optional VIP tagging of qualified customers.
- VIP candidate CSV
- Optional VIP tags applied via customerUpdate
By the numbers
- 3 GraphQL operations (customers, orders, customerUpdate)
- default top_pct 5%
- default min_orders 2
Files
Purpose
Ranks customers by lifetime spend and order frequency, identifies the top N% (by value, frequency, or both), and outputs a CSV of VIP candidates. Optionally applies a VIP tag to qualified customers via customerUpdate. Used to build loyalty segments, prioritize white-glove support, or seed exclusive-access campaigns. The lifetime spend and order count are pulled directly from Shopify customer aggregates — no external CRM required.
Prerequisites
- Authenticated Shopify CLI session:
shopify store auth --store <domain> --scopes read_customers,read_orders,write_customers - API scopes:
read_customers,read_orders,write_customers(only iftag_customers: true)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| format | string | no | human | Output format: human or json |
| dry_run | bool | no | true | Preview VIP list without applying tags |
| rank_by | string | no | spend | Ranking strategy: spend (lifetime value), frequency (order count), or both (composite score) |
| top_pct | float | no | 5 | Top percentile to qualify as VIP (e.g., 5 = top 5%) |
| min_orders | integer | no | 2 | Minimum lifetime orders to be eligible |
| min_spend | float | no | 0 | Minimum lifetime spend (shop currency) to be eligible |
| tag_customers | bool | no | false | If true, apply VIP tag to qualified customers via customerUpdate |
| tag | string | no | vip | Tag string applied when tag_customers: true |
Safety
⚠️ Whentag_customers: true, Step 3 executescustomerUpdatemutations that mutate customer tag lists. Tags persist until manually removed. Run withdry_run: truefirst to confirm the VIP list and qualifying thresholds. The default isdry_run: true— you must explicitly setdry_run: falseandtag_customers: trueto apply tags.
Workflow Steps
1. OPERATION: customers — query Inputs: first: 250, query: "orders_count:>=<min_orders>", select id, displayName, defaultEmailAddress { emailAddress }, numberOfOrders, amountSpent { amount currencyCode }, tags, pagination cursor Expected output: All customers meeting min_orders threshold; paginate until hasNextPage: false
2. OPERATION: orders — query (only when ranking by frequency, for recency annotation) Inputs: For each top candidate: query: "customer_id:<id>", first: 1, sortKey: CREATED_AT, reverse: true Expected output: Most recent order per candidate to annotate the export
3. Filter to amountSpent.amount >= min_spend. Score each customer: spend → spend; frequency → orders; both → 0.6 × normalized spend + 0.4 × normalized frequency. Take the top top_pct%.
4. OPERATION: customerUpdate — mutation (only if tag_customers: true and dry_run: false) Inputs: input: { id: <customer_id>, tags: [...existing_tags, <tag>] } Expected output: customer.id, customer.tags, userErrors
GraphQL Operations
# customers:query — validated against api_version 2025-01
query VIPCandidateCustomers($first: Int!, $after: String, $query: String) {
customers(first: $first, after: $after, query: $query) {
edges {
node {
id
displayName
firstName
lastName
defaultEmailAddress {
emailAddress
}
numberOfOrders
amountSpent {
amount
currencyCode
}
tags
createdAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}# orders:query — validated against api_version 2025-01
query VIPLastOrder($query: String!) {
orders(first: 1, query: $query, sortKey: CREATED_AT, reverse: true) {
edges {
node {
id
name
createdAt
totalPriceSet {
shopMoney { amount currencyCode }
}
}
}
}
}# customerUpdate:mutation — validated against api_version 2025-01
mutation CustomerUpdateVipTag($input: CustomerInput!) {
customerUpdate(input: $input) {
customer {
id
displayName
tags
}
userErrors {
field
message
}
}
}Session Tracking
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: VIP Customer Identifier ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>If dry_run: true, prefix every mutation step with [DRY RUN] and do not execute it.
On completion, emit:
For format: human (default):
══════════════════════════════════════════════
VIP CUSTOMER REPORT
Customers scanned: <n>
Eligible (≥ min): <n>
VIPs (top <pct>%): <n>
Threshold spend: $<amount>
Threshold orders: <n>
Customers tagged: <n> (or "skipped — dry_run")
Top 10 VIPs by <rank_by>:
<name> Spend: $<amount> Orders: <n> Last: <date>
Output: vip_customers_<date>.csv
══════════════════════════════════════════════For format: json, emit:
{
"skill": "vip-customer-identifier",
"store": "<domain>",
"dry_run": true,
"rank_by": "spend",
"outcome": {
"customers_scanned": 0,
"eligible": 0,
"vips_identified": 0,
"threshold_spend": 0,
"customers_tagged": 0,
"errors": 0,
"output_file": "vip_customers_<date>.csv"
}
}Output Format
CSV file vip_customers_<YYYY-MM-DD>.csv with columns: customer_id, name, email, lifetime_spend, currency, orders_count, last_order_date, composite_score, rank, tag_applied
Error Handling
| Error | Cause | Recovery |
|---|---|---|
THROTTLED | API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
userErrors on customerUpdate | Customer not found or tag conflict | Log, skip, continue |
Fewer eligible than top_pct% | Small customer base | Lower min_orders/min_spend |
| Multi-currency stores | currencyCode varies | Convert via shop default before ranking |
Best Practices
- Use
rank_by: bothto balance whales with loyalists — pure spend ranking can over-index on one-time large purchases. - Re-run quarterly with a date-stamped tag (e.g.,
vip-2026-Q2) so lapsed VIPs roll off rather than accumulating permanently. - Pair with
customer-win-back— VIPs who become inactive should be flagged for high-priority re-engagement. - Run with
dry_run: truefirst; review the threshold spend value to confirm the cutoff matches your VIP definition.
Related skills
FAQ
Does it tag customers automatically?
Only if tag_customers is true and dry_run is false; both default to safe values.
How are VIPs ranked?
By lifetime spend, order frequency, or a composite score, taking the top percentile.