Skip to content
Back to skills

Shopify Admin Delivery Time Analysis

ASecurity

Read-only: calculates average time from fulfillment creation to delivery by carrier using fulfillment and order data.

  • 181 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 28, 2026
businessgonodeapiperformance

Works with

  • claude code
  • cursor
  • cli
  • api

Security analysis

A100/100

Scanned May 28, 2026

npx -y skills add 40RTY-ai/shopify-admin-skills --skill shopify-admin-delivery-time-analysis --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Shopify Admin Delivery Time Analysis?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Shopify Admin Delivery Time Analysis
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/40rty-ai-shopify-admin-delivery-time-analysis/badge)](https://www.skillsdirectory.com/skills/40rty-ai-shopify-admin-delivery-time-analysis)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: shopify-admin-delivery-time-analysis
role: fulfillment-ops
description: "Read-only: calculates average time from fulfillment creation to delivery by carrier using fulfillment and order data."
toolkit: shopify-admin, shopify-admin-execution
api_version: "2025-01"
graphql_operations:
  - orders:query
  - fulfillmentOrders:query
status: stable
compatibility: Claude Code, Cursor, Codex, Gemini CLI
---

## Purpose
Analyzes fulfilled orders to calculate average transit time (fulfillment created → delivered) broken down by carrier. Surfaces which carriers are consistently slow or missing delivery confirmations. Read-only — no mutations.

## Prerequisites
- Authenticated Shopify CLI session: `shopify store auth --store <domain> --scopes read_orders`
- API scopes: `read_orders`

## Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| days_back | integer | no | 30 | Lookback window for fulfilled orders |
| min_orders | integer | no | 5 | Minimum orders per carrier to include in averages |
| location_id | string | no | — | Filter by fulfillment location (optional) |
| format | string | no | human | Output format: `human` or `json` |

## Safety

> ℹ️ Read-only skill — no mutations are executed. Safe to run at any time.

## Workflow Steps

1. **OPERATION:** `orders` — query
   **Inputs:** `query: "fulfillment_status:shipped created_at:>='<NOW - days_back days>'"`, `first: 250`, pagination cursor
   **Expected output:** Orders with `fulfillments { createdAt, updatedAt, deliveredAt, trackingInfo { company } }`; paginate until `hasNextPage: false`

2. Calculate transit times per carrier: `deliveredAt - createdAt` (skip orders where `deliveredAt` is null)

3. **OPERATION:** `fulfillmentOrders` — query (optional, for location breakdown)
   **Inputs:** `assignedLocationId: <location_id>`, `status: CLOSED`, `first: 250`
   **Expected output:** Fulfilled orders per location for location-level segmentation

## GraphQL Operations

```graphql
# orders:query — validated against api_version 2025-01
query FulfilledOrders($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        createdAt
        fulfillments {
          id
          createdAt
          updatedAt
          deliveredAt
          status
          trackingInfo {
            company
            number
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```graphql
# fulfillmentOrders:query — validated against api_version 2025-01
query FulfillmentOrdersByLocation($locationId: ID!, $after: String) {
  fulfillmentOrders(
    assignedLocationId: $locationId
    first: 250
    after: $after
    query: "status:closed"
  ) {
    edges {
      node {
        id
        assignedLocation {
          location {
            id
            name
          }
        }
        order {
          id
          name
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Session Tracking

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

**On start**, emit:
```
╔══════════════════════════════════════════════╗
║  SKILL: Delivery Time Analysis               ║
║  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>
```

**On completion**, emit:

For `format: human` (default):
```
══════════════════════════════════════════════
DELIVERY TIME ANALYSIS  (<days_back> days)
  Orders analyzed:     <n>
  With delivery data:  <n>

  Carrier              Orders  Avg Days  Min  Max
  ─────────────────────────────────────────────
  UPS                  <n>     <d>       <d>  <d>
  USPS                 <n>     <d>       <d>  <d>
  FedEx                <n>     <d>       <d>  <d>
  (carriers below min_orders threshold excluded)
  Output: delivery_analysis_<date>.csv
══════════════════════════════════════════════
```

For `format: json`, emit:
```json
{
  "skill": "delivery-time-analysis",
  "store": "<domain>",
  "period_days": 30,
  "carriers": [
    { "name": "UPS", "orders": 0, "avg_days": 0, "min_days": 0, "max_days": 0 }
  ],
  "output_file": "delivery_analysis_<date>.csv"
}
```

## Output Format
CSV file `delivery_analysis_<YYYY-MM-DD>.csv` with columns:
`order_name`, `fulfillment_id`, `carrier`, `fulfilled_at`, `delivered_at`, `transit_days`

## Error Handling
| Error | Cause | Recovery |
|-------|-------|----------|
| `THROTTLED` | API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
| `deliveredAt` is null | Carrier hasn't confirmed delivery | Exclude from averages, count as "in transit" |
| No fulfilled orders in window | Period too short or no orders | Exit with summary: 0 orders |

## Best Practices
- Set `min_orders: 10` for statistically meaningful averages — carriers with fewer orders will skew results.
- `deliveredAt` is populated only when the carrier confirms delivery via tracking events; some carriers do not report this, so null values are expected.
- Run monthly to track carrier performance over time and inform carrier contract negotiations.
- Cross-reference with the `wismo-bulk-status-report` skill to correlate slow delivery carriers with WISMO ticket volume.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.