Skip to content
Back to skills

Shopify Admin Bulk Fulfillment Creation

ASecurity

Batch-fulfill open fulfillment orders with tracking numbers. Supports partial fulfillment and customer notification toggle.

  • 181 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 28, 2026
businessnodetestingapi

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-bulk-fulfillment-creation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Shopify Admin Bulk Fulfillment Creation?

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

Security grade badge for Shopify Admin Bulk Fulfillment Creation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/40rty-ai-shopify-admin-bulk-fulfillment-creation/badge)](https://www.skillsdirectory.com/skills/40rty-ai-shopify-admin-bulk-fulfillment-creation)

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-bulk-fulfillment-creation
role: fulfillment-ops
description: "Batch-fulfill open fulfillment orders with tracking numbers. Supports partial fulfillment and customer notification toggle."
toolkit: shopify-admin, shopify-admin-execution
api_version: "2025-01"
graphql_operations:
  - fulfillmentOrders:query
  - fulfillmentCreate:mutation
status: stable
compatibility: Claude Code, Cursor, Codex, Gemini CLI
---

## Purpose
Queries all open fulfillment orders for a location and batch-creates fulfillments with tracking numbers in a single workflow. No third-party app required — this skill handles the fulfillment creation layer; carrier label generation requires a separate tool or carrier integration.

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

## Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| location_id | string | yes | — | GID of the fulfillment location (e.g., gid://shopify/Location/123) |
| tracking_numbers | array | no | [] | List of `{fulfillment_order_id, tracking_number, tracking_url, carrier}` objects |
| notify_customer | bool | no | true | Send shipping confirmation email to customer |
| dry_run | bool | no | true | Preview fulfillments without executing mutations |
| format | string | no | human | Output format: `human` or `json` |

## Safety

> ⚠️ `fulfillmentCreate` is irreversible — fulfilled orders cannot be unfulfilled via the API. Run with `dry_run: true` first to confirm the list of fulfillment orders before committing. Each mutation creates one fulfillment record per fulfillment order.

## Workflow Steps

1. **OPERATION:** `fulfillmentOrders` — query
   **Inputs:** `assignedLocationId: <location_id>`, `status: OPEN`, `first: 250`, pagination cursor
   **Expected output:** List of open fulfillment orders with `id`, `order { name }`, `lineItems`; paginate until `hasNextPage: false`

2. **OPERATION:** `fulfillmentCreate` — mutation
   **Inputs:** For each fulfillment order: `fulfillmentOrderId`, `trackingInfo { company, number, url }`, `notifyCustomer`
   **Expected output:** `fulfillment { id, status, trackingInfo }`, `userErrors`

## GraphQL Operations

```graphql
# fulfillmentOrders:query — validated against api_version 2025-01
query OpenFulfillmentOrders($locationId: ID!, $after: String) {
  fulfillmentOrders(
    assignedLocationId: $locationId
    first: 250
    after: $after
    query: "status:open"
  ) {
    edges {
      node {
        id
        status
        order {
          id
          name
        }
        lineItems(first: 10) {
          edges {
            node {
              id
              remainingQuantity
              variant {
                sku
                title
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

```graphql
# fulfillmentCreate:mutation — validated against api_version 2025-01
mutation FulfillmentCreate($fulfillment: FulfillmentInput!) {
  fulfillmentCreate(fulfillment: $fulfillment) {
    fulfillment {
      id
      status
      trackingInfo {
        company
        number
        url
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

## Session Tracking

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

**On start**, emit:
```
╔══════════════════════════════════════════════╗
║  SKILL: Bulk Fulfillment Creation            ║
║  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
  Open fulfillment orders found: <n>
  Fulfillments created:          <n>
  Customer notifications sent:   <n>
  Errors:                        <n>
  Output:                        fulfillment_batch_<date>.csv
══════════════════════════════════════════════
```

For `format: json`, emit:
```json
{
  "skill": "bulk-fulfillment-creation",
  "store": "<domain>",
  "started_at": "<ISO8601>",
  "completed_at": "<ISO8601>",
  "dry_run": true,
  "steps": [
    { "step": 1, "operation": "OpenFulfillmentOrders", "type": "query", "params_summary": "location <id>, status open", "result_summary": "<n> orders", "skipped": false },
    { "step": 2, "operation": "FulfillmentCreate", "type": "mutation", "params_summary": "<n> fulfillments", "result_summary": "<n> created", "skipped": false }
  ],
  "outcome": {
    "orders_found": 0,
    "fulfillments_created": 0,
    "notifications_sent": 0,
    "errors": 0,
    "output_file": "fulfillment_batch_<date>.csv"
  }
}
```

## Output Format
CSV file `fulfillment_batch_<YYYY-MM-DD>.csv` with columns:
`order_name`, `fulfillment_order_id`, `fulfillment_id`, `tracking_number`, `carrier`, `notify_customer`, `status`

## Error Handling
| Error | Cause | Recovery |
|-------|-------|----------|
| `THROTTLED` | API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
| `userErrors` on fulfillmentCreate | Already fulfilled or invalid tracking | Log error, skip order, continue |
| `FULFILLMENT_ORDER_LINE_ITEM_QUANTITY_MISMATCH` | Partial fulfillment quantity mismatch | Log warning, attempt partial fulfillment |
| No open orders at location | Location has no pending work | Exit with summary: 0 orders found |

## Best Practices
- Always run with `dry_run: true` first — fulfillments cannot be undone via the Admin API.
- Pass `notify_customer: false` during batch testing or for B2B orders where customers do not expect individual shipment emails.
- Provide tracking numbers in the `tracking_numbers` parameter before running; unfulfilled orders without tracking will still create fulfillments — confirm this is intentional.
- For large batches (100+ orders), the mutation loop will hit rate limits — the skill retries automatically with a 2-second back-off.

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.