Run a Shopify Admin GraphQL bulk mutation to update metafield values across thousands of products using stagedUploadsCreate and bulkOperationRunMutation
Prepare a JSONL file where each line is a valid JSON object containing the mutation variables for one product's metafield update — e.g., `{"input": {"id": "gid://shopify/Product/123", "metafields": [{"namespace": "custom", "key": "size_guide", "value": "...", "type": "single_line_text_field"}]}}`
Call `stagedUploadsCreate(input: [{ filename: "metafields_update.jsonl", mimeType: "text/jsonl", httpMethod: POST, resource: BULK_MUTATION_VARIABLES }])` to get a pre-signed upload URL and staged target parameters
Upload the JSONL file to the staged upload URL using a multipart POST with the parameters returned by stagedUploadsCreate; the file must be uploaded before calling bulkOperationRunMutation
Call `bulkOperationRunMutation(mutation: "mutation productMetafieldUpdate($input: ProductInput!) { productUpdate(input: $input) { product { id } userErrors { field message } } }", stagedUploadPath: $uploadKey)` to start the bulk operation
Poll `currentBulkOperation { id status errorCode }` until `status` is `COMPLETED` — also subscribe to the `bulk_operations/finish` webhook to receive notification without polling
Download the results JSONL from `currentBulkOperation.url` (available when status is COMPLETED) and parse each line to identify any `userErrors` that indicate failed individual mutations
Known gotchas
Each line in the JSONL file must be a self-contained JSON object with the exact variable keys expected by the mutation — malformed lines silently fail and appear as errors in the results JSONL, not as a top-level operation failure
Only one bulk operation can run at a time per shop; calling bulkOperationRunMutation while another is in progress returns an error — check currentBulkOperation status and cancel if needed with bulkOperationCancel
The `stagedUploadPath` parameter in bulkOperationRunMutation must be the `path` field returned by stagedUploadsCreate, not the full signed URL — using the full URL causes the operation to fail with a path not found error
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp