shopify-admin-inventory-transfer-between-locations

SkillCommerce & finance

Moves inventory units from one location to another by decrementing the source and incrementing the destination.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the shopify-admin-inventory-transfer-between-locations skill

What this skill tells your AI

The instructions your AI receives, as published by 40rty-ai/shopify-admin-skills in skills/merchandising/shopify-admin-inventory-transfer-between-locations/SKILL.md and read by ahel’s review.

Purpose

Transfers a specified quantity of inventory from a source location to a destination location using paired inventory adjustments (decrement source, increment destination). Used for inter-warehouse rebalancing, pre-positioning stock before a sale, or redistributing inventory after a location change. Replaces manual inventory transfer in Shopify Admin.

Prerequisites

  • Authenticated Shopify CLI session: shopify store auth --store <domain> --scopes read_products,write_inventory,read_inventory
  • API scopes: read_products, read_inventory, write_inventory
  • Both source and destination must be active Shopify locations

Parameters

ParameterTypeRequiredDefaultDescription
storestringyesStore domain (e.g., mystore.myshopify.com)
source_location_idstringyesGID of the location to move stock FROM
destination_location_idstringyesGID of the location to move stock TO
transfersarrayyesList of {sku, quantity} objects to transfer
dry_runboolnotruePreview adjustments without executing mutations
formatstringnohumanOutput format: human or json

Safety

⚠️ inventoryAdjustQuantities directly modifies inventory levels. Decrementing the source below zero is possible if the quantity exceeds available stock — the skill will warn but Shopify does not block negative adjustments. Run with dry_run: true to verify available quantities at the source before committing. This does NOT create a transfer order record in Shopify; it is a direct adjustment.

Workflow Steps

  1. OPERATION: locations — query Inputs: first: 50 Expected output: All locations with id, name — validate source and destination IDs exist

  2. OPERATION: inventoryItems — query Inputs: Batch lookup by SKU to get inventoryItem.id for each transfer SKU Expected output: Inventory items with current quantities at source location

  3. Validate: for each SKU, confirm available >= quantity at source. Warn if not but proceed if dry_run: false

  4. OPERATION: inventoryAdjustQuantities — mutation Inputs: Two changes per SKU: { inventoryItemId, locationId: source, delta: -quantity, reason: "correction" } and { inventoryItemId, locationId: destination, delta: +quantity, reason: "correction" } Expected output: inventoryAdjustmentGroup { changes { delta, location } }, userErrors

GraphQL Operations

# locations:query — validated against api_version 2025-01
query ActiveLocations {
  locations(first: 50, includeInactive: false) {
    edges {
      node {
        id
        name
        isActive
        fulfillsOnlineOrders
      }
    }
  }
}
# inventoryItems:query — validated against api_version 2025-01
query InventoryLevelsAtLocation($ids: [ID!]!) {
  nodes(ids: $ids) {
    ... on InventoryItem {
      id
      sku
      inventoryLevels(first: 20) {
        edges {
          node {
            location {
              id
              name
            }
            quantities(names: ["available", "on_hand"]) {
              name
              quantity
            }
          }
        }
      }
    }
  }
}
# inventoryAdjustQuantities:mutation — validated against api_version 2025-01
mutation InventoryAdjustQuantities($input: InventoryAdjustQuantitiesInput!) {
  inventoryAdjustQuantities(input: $input) {
    inventoryAdjustmentGroup {
      createdAt
      reason
      changes {
        delta
        quantityAfterChange
        item {
          id
          sku
        }
        location {
          id
          name
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}

Session Tracking

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

On start, emit:

╔══════════════════════════════════════════════╗
║  SKILL: Inventory Transfer Between Locations ║
║  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):

══════════════════════════════════════════════
OUTCOME SUMMARY
  SKUs transferred:   <n>
  Total units moved:  <n>
  Warnings (low stock): <n>
  Errors:             <n>
  Output:             inventory_transfer_<date>.csv
══════════════════════════════════════════════

For format: json, emit:

{
  "skill": "inventory-transfer-between-locations",
  "store": "<domain>",
  "started_at": "<ISO8601>",
  "dry_run": true,
  "source_location": "<name>",
  "destination_location": "<name>",
  "outcome": {
    "skus_transferred": 0,
    "units_moved": 0,
    "warnings": 0,
    "errors": 0,
    "output_file": "inventory_transfer_<date>.csv"
  }
}

Output Format

CSV file inventory_transfer_<YYYY-MM-DD>.csv with columns: sku, product_title, inventory_item_id, source_location, destination_location, quantity_transferred, source_qty_before, source_qty_after, destination_qty_before, destination_qty_after

Error Handling

ErrorCauseRecovery
THROTTLEDAPI rate limit exceededWait 2 seconds, retry up to 3 times
SKU not foundSKU not in catalogLog warning, skip transfer for that SKU
userErrors on adjustmentLocation not stocking itemLog error, skip SKU, continue
Quantity would go negativeTransferring more than availableLog warning; abort SKU if dry_run: false

Best Practices

  • Always run with dry_run: true first — the skill verifies available quantities and shows exactly what will change.
  • This creates raw inventory adjustments, not a transfer order. For audit trail purposes, add a note in the reason field and document the transfer separately.
  • For large transfers (50+ SKUs), run during off-peak hours to avoid interfering with live inventory reads by the storefront.
  • Pair with multi-location-inventory-audit to identify which locations have excess stock before deciding transfer quantities.

Signals

GitHub stars
187
Forks
18
Last commit
Aug 2026

ahel review

  • S4info
    community integration — published by 40rty-ai, not shopify

Automated review, not a security audit. Ruleset v1.

Advanced
Catalog kind
skill
Gateway key
shopify-admin-inventory-transfer-between-locations
Source
github.com/40rty-ai/shopify-admin-skills