From shopify-admin-skills
Batch-fulfills open Shopify fulfillment orders at a location with tracking numbers via GraphQL mutations. Supports partial fulfillment, customer notifications, dry-run previews, and pagination.
npx claudepluginhub 40rty-ai/shopify-admin-skills --plugin shopify-admin-skillsThis skill uses the workspace's default tool permissions.
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.
Batch-updates tracking numbers and URLs on existing Shopify fulfillments via GraphQL mutations. Use for carrier reassignments, label reprints, or 3PL corrections.
Manages Shopify orders, customers, and fulfillments via GraphQL Admin API. Query orders, process fulfillments, handle customer records, create draft orders.
Guides Shopify order management via GraphQL: lifecycle, FulfillmentOrder, returns/refunds, draft orders, editing, transactions, metafields, risk analysis.
Share bugs, ideas, or general feedback.
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.
shopify store auth --store <domain> --scopes read_orders,write_fulfillmentsread_orders, write_fulfillments| 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 |
⚠️
fulfillmentCreateis irreversible — fulfilled orders cannot be unfulfilled via the API. Run withdry_run: truefirst to confirm the list of fulfillment orders before committing. Each mutation creates one fulfillment record per fulfillment order.
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
OPERATION: fulfillmentCreate — mutation
Inputs: For each fulfillment order: fulfillmentOrderId, trackingInfo { company, number, url }, notifyCustomer
Expected output: fulfillment { id, status, trackingInfo }, userErrors
# 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
}
}
}
# 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
}
}
}
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:
{
"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"
}
}
CSV file fulfillment_batch_<YYYY-MM-DD>.csv with columns:
order_name, fulfillment_order_id, fulfillment_id, tracking_number, carrier, notify_customer, status
| 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 |
dry_run: true first — fulfillments cannot be undone via the Admin API.notify_customer: false during batch testing or for B2B orders where customers do not expect individual shipment emails.tracking_numbers parameter before running; unfulfilled orders without tracking will still create fulfillments — confirm this is intentional.