Install
openclaw skills install @artificialintelligently/shopify-admin-proGuarded Shopify Admin for OpenClaw: everything shopify-audit-pro does, plus acting as the store admin. Safety first: nothing is written without a preview and your explicit confirmation, delete/refund/cancel/publish and other high-risk actions need a second exact confirmation, a failed write is never blindly retried, your token goes only to your own *.myshopify.com store (no relay, no third-party plugin), secrets are never typed in chat, and a PII-free audit log records every call. Then the admin power: audits and reports, plus products, inventory, orders, fulfillment, refunds, discounts, customers, themes and bulk edits via the Admin GraphQL API. Only the scopes you grant are usable.
openclaw skills install @artificialintelligently/shopify-admin-proGuarded Shopify Admin GraphQL access: audit and report like shopify-audit-pro, and make changes like an
admin. One helper (scripts/shopify_api.py, Python standard library only, no installs) does all store I/O,
so the safety rules are enforced by code, not by good intentions.
Helper path: {baseDir}/scripts/shopify_api.py (below: shopify).
Only need audits and reports, with no ability to change anything? Use shopify-audit-pro instead.
Status (v1.0.1): reads, the safety guards and the mutation shapes are tested (live reads, a stubbed-network guard suite, and the live Shopify schema). A confirmed live write has not yet been run against a real store. Try your first writes on a development store, with a low-risk change you can watch.
query, paginate and bulk-query refuse any document containing a mutation
or subscription (comments and strings are stripped first, so they cannot hide one).mutate. One mutation per call. Nothing is sent without --confirm.
Without it you get a preview (the mutation names, risk level and variables) and exit code 2.--confirm-high-risk <names> exactly as previewed.userErrors (or a variant such as orderCancelUserErrors) means nothing was applied (exit code 3).<store>.myshopify.com (strict domain
check).bulk-query downloads Shopify's result file only from
https://storage.googleapis.com. No credentials are sent and an existing file is never overwritten.~/.openclaw/logs/shopify-audit.jsonl
(mode 600): time, store, API version, mutation names, a hash of the payload, error counts. Never the token,
never customer data.--redact-pii masks email, phone, names and addresses in output.| What | Why |
|---|---|
https://<your-store>.myshopify.com | Token exchange, Admin GraphQL reads, and confirmed writes |
https://storage.googleapis.com (only for bulk-query) | Downloading Shopify's bulk-export result file |
~/.openclaw/secrets/shopify.env (optional, you create it, must be mode 600) | Holds SHOPIFY_STORE_DOMAIN, SHOPIFY_CLIENT_ID, SHOPIFY_CLIENT_SECRET on hosts where the secret store is not injected. Only those SHOPIFY_* keys are read. |
~/.openclaw/logs/shopify-audit.jsonl | Append-only audit log (mode 600) |
--file / --vars-file / --out paths you pass | Query text (.graphql/.gql/.txt), variables (.json), and a new output file |
It never runs other programs, never installs anything, never edits memory or agent settings, and never sends data anywhere except Shopify.
bulk-query internally starts Shopify's bulkOperationRunQuery. That is an asynchronous read export. It needs
only read scopes and changes no store data.
references/safety-and-scopes.md), release a version, install it on the store, then
copy the Client ID and Client Secret from the app's Settings.
Legacy apps created before 2026 still work: use their static SHOPIFY_ACCESS_TOKEN.write_* scopes only when a task needs them: release a new app version and approve
it on the store. Prefer a separate app per tier so a read-only task cannot write even if something goes wrong.secrets tool), or, on a node host, create
~/.openclaw/secrets/shopify.env yourself with hidden input and chmod 600 it. The agent must never create
that file with the secret value and must never ask for the secret in chat.
Lines: SHOPIFY_STORE_DOMAIN=my-store.myshopify.com, SHOPIFY_CLIENT_ID=..., SHOPIFY_CLIENT_SECRET=....shopify scopes and shopify versions.Audit and report (read)
Act as admin (write, each behind preview and confirmation)
shopify query --query '<graphql>' [--vars '{}'] [--file q.graphql] [--vars-file v.json] [--redact-pii]
shopify paginate --query '<graphql with $cursor + pageInfo>' --path products [--max-pages 20]
shopify bulk-query --file q.graphql --out ~/.openclaw/workspace/tmp/x.jsonl # large exports, new file only
shopify mutate --query '<one mutation>' --vars '{}' # preview only, sends nothing
shopify mutate ... --confirm [--confirm-high-risk refundCreate] # actually send
shopify scopes | versions | --version
Exit codes: 0 ok, 1 error (including a refused document), 2 confirmation required (nothing sent), 3 Shopify
userErrors (HTTP 200 but NOT applied, treat as failure).
mutate without --confirm, show the user the preview in plain words
(what changes, on what, how many, whether a customer is emailed), and re-run with --confirm only after an
explicit yes for that change. Approval for one write is not approval for the next.status: DRAFT or archiving over deletion;
deletes are rarely reversible. Save an old-to-new table so a change can be reverted.suggestedRefund),
quote the amount and currency back to the user, then confirm.notifyCustomer: true, invoices, fulfillment emails): say so and confirm.userErrors: []. Exit code 3 means nothing was applied.--redact-pii unless the task needs the real values. Don't paste customer details
into memory files, group chats or logs. Never contact customers from Shopify data without an approved message.{ __type(name:"X"){ inputFields{ name } fields{ name } } }) before retrying. Shopify changes inputs between versions.read_all_orders. Customer fields may be
null until the app is approved for protected customer data. Say so.scopes, paginate, bulk-query and the mutate guards have been tested
(guards against a stubbed network). A confirmed live write has not yet been exercised on a store; the first one
should be a low-risk change (a tag on a draft product) that the user watches.| Need | Use |
|---|---|
| A few records / lookups | query |
| Up to a few thousand rows | paginate |
| Whole catalog / all orders / history | bulk-query (async JSONL; one at a time per shop) |
| Sales/traffic analytics | ShopifyQL via shopifyqlQuery (needs read_reports), see the cookbook |
| Change data | mutate (single operation per call) |
references/graphql-cookbook.md: ready read queries and write mutations for products, orders, customers, inventory, fulfillment, refunds, discounts, shipping, themes, policies and ShopifyQL.references/workflows.md: playbooks including the pre-opening audit, daily ops brief, refund, fulfillment and bulk update.references/safety-and-scopes.md: scope tiers, PII rules, token hygiene, incident response.