Shopify: generate an Admin token and let the agent make changes
Shopify connects at three levels. The store domain alone unlocks anonymous catalog, product and cart tools. Adding an Admin API access token (or custom-app client credentials, or the OAuth app) unlocks read-only orders, products, customers and a server-side sales summary. With write scopes on that connection, the agent can also change the store — discount codes, product, price, inventory and collection changes — each going through the approval gate before it runs, and the irreversible or money-moving ones always waiting for a person.
The three connection tiers
Pick the tier by what you want the agent to do. You can start at tier 1 and upgrade later — adding a token to an existing store never breaks the storefront tools.
| Tier | What you provide | What the agent can do |
|---|---|---|
| 1 — Storefront | Store domain only | Search the public catalog, read product details, build a cart and get a checkout link, search store policies and FAQs. No credentials at all. |
| 2 — Admin read | Admin API access token, or custom-app client ID + secret, or the OAuth app | Everything above, plus orders, admin-side products (including DRAFT/ARCHIVED and live inventory), customers, shop info, and an aggregated sales summary. |
| 3 — Admin write | The same connection, with write scopes granted (ticked on the token, or on the Shopify app's consent screen) | Everything above, plus store changes — typed tools for discount codes, inventory, product copy / tags / SEO / status, variant prices, product media and the app's web pixel, and Admin GraphQL mutations for anything else your scopes allow. Every change is approval-gated; deletions, money-moving mutations, repricing, an absolute stock set, deactivating a code, a discount of 50 % off or more and a product status flip wait for a person. |
Generate a Shopify Admin API access token
This is the custom-app path — the fastest way to get a token, and the one where you choose the scopes yourself, write scopes included. You need to be the store owner or a staff account with the “Develop apps” permission.
- 1In Shopify admin, go to Settings → Apps and sales channels → Develop apps (since 2026 this hands off to the Shopify Dev Dashboard — same flow, newer screens).
- 2Create an app and give it a name (e.g. “Agent Planners”).
- 3Open Configuration → Admin API integration, and tick the scopes you want (see the scope table below) — include write_* scopes if you want approval-gated store changes.
- 4Save, then install the app on your store from the API credentials / app settings screen.
- 5On API credentials, click “Reveal token once” next to Admin API access token — it starts with
shpat_and Shopify shows it exactly once, so copy it now (check your scopes BEFORE revealing). - 6In Agent Planners, open Integrations → Shopify → Connect store → “Connect with an Admin API token from a custom app”, enter your store domain, choose “+ Admin token”, paste the token, and click “Validate + connect”.
Which scopes to grant
Grant only what you actually want the agent to reach. A missing scope isn't a crash — Shopify answers with an ACCESS_DENIED message naming the scope, so you can add it and retry. The one exception is read_all_orders: without it Shopify silently serves only the last 60 days of orders.
| You want | Scope to tick |
|---|---|
| Orders, revenue, the sales summary, fulfillments and tracking | read_orders |
| Admin product list, inventory counts, draft/archived products | read_products |
| Customer list and lifetime spend | read_customers |
| Inventory levels | read_inventory |
| The agent to create or edit products and prices | write_products |
| The agent to adjust inventory | write_inventory |
| Locations — the ids every inventory change needs | read_locations |
| Discount codes (list) | read_discounts |
| The agent to create, edit, activate, deactivate or delete discount codes | write_discounts |
| Returns | read_returns |
| Shopify Marketing activities (read only) | read_marketing_events |
| The app's web pixel — works only when the app ships a web-pixel extension | write_pixels + read_customer_events |
| Orders older than 60 days, in order reads and the sales summary | read_all_orders — without it Shopify silently serves the last 60 days |
| Sessions and conversion rate (ShopifyQL) | read_reports, plus Shopify's Level 2 protected-customer-data approval |
The other two ways to connect
- Client credentials — paste the custom app's client ID and client secret instead of a token. Agent Planners exchanges them for a short-lived Bearer automatically and refreshes it before expiry, so there's no long-lived token sitting in storage.
- Shopify app (OAuth) — on Integrations → Shopify → Connect store, click Install from Shopify: Shopify asks you to sign in and choose the store, then open Agent Planners in your Shopify admin (Apps) and click Connect to a workspace. No store domain to type, no custom app to build and no token to copy. The consent screen lists exactly the scopes this deployment requests (
read_products,read_orders,read_customers,read_inventoryby default; an operator can add write scopes), the store's row shows what Shopify actually granted, and Sync scopes re-reads it. Every typed write checks that grant first and answers with the missing scope instead of failing mid-run.
What the agent can read
| Capability | What comes back |
|---|---|
| Sales summary | Server-side aggregation over the window: order count, revenue, average order value, revenue by day, orders by financial status, and top products by units. The totals are computed in code, so the model never re-adds order rows by hand. |
| Orders | Recent orders with name, date, financial and fulfilment status, total and line items — in the shop's own currency, with the date window anchored to the shop's timezone. |
| Products (admin view) | Title, status, vendor, product type, live inventory and price range — including DRAFT and ARCHIVED products the public storefront never shows. |
| Customers | Order count and lifetime spend per customer. The name (Shopify's display name, which falls back to the email or phone) comes back only when a person's own request in an interactive task asks for identified customers — never over MCP, in an autonomous run, on a schedule or on a dashboard. |
| Shop info | Name, currency, timezone, myshopify and primary domain. |
| Admin GraphQL query | A generic read gateway for anything the wrappers don't cover. Mutation documents are rejected outright on this tool. |
| Storefront catalog / cart / policies | Public product search, product details, cart building with a checkout URL, and policy/FAQ search — available with no credentials. |
| Locations and inventory levels | The store's locations, and available / on-hand / committed / incoming per location for a product's variants — the pairs an inventory change needs (read_locations, read_inventory). |
| Discount codes, returns, fulfillments | Code and automatic discounts with status, dates, usage and value (the API's 0–1 percentage is shown as a percent too); orders with returns; fulfillments with tracking and delivery dates. |
| Marketing activities, app scopes, web pixel | Shopify Marketing's own campaign records with their UTMs and spend; what the store's authorization grants right now versus the row; the app's web pixel. |
| Landing URL | A UTM-tagged storefront URL on the primary domain for an ad's destination — existing parameters kept byte for byte, values encoded once, nothing written. |
How the agent makes changes to your store
Store changes run through one Admin GraphQL mutation gateway, so anything your connection is scoped for is reachable — product create/update/delete, variant and price updates, inventory adjustments, collection management, and so on. You describe the change in plain language; the agent writes the mutation and shows it to you before it runs.
Since rev808 the common changes are typed tools with their own checks: create / update / activate / delete a discount code, adjust inventory by a delta (an idempotency key is minted per request) or set it absolutely, edit product copy, tags, SEO and status, reprice variants, add product media from public URLs, and manage the app's web pixel. Every one checks the store's granted scope first and pauses for approval; deleting a code or the pixel, an absolute inventory set, repricing, deactivating a code (or ending / postponing it by date), a discount of 50 % off or more (typed, or a discount written through the mutation gateway) and a product status flip always wait for a person.
- 1Write the goal in the Workspace, e.g. “Mark every product with zero inventory as draft.”
- 2The agent reads the store first to find exactly which products match — you see the list before anything changes.
- 3Each mutation stops at the approval gate showing the exact GraphQL document and variables it will send.
- 4Approve (in-app or by email magic-link) and it runs once. Reject and that step is skipped without aborting the rest of the run.
- 5The result is verified and written to the audit log with before/after detail.
read_* scopes only and run a few audits first. Add write_products when you trust the plans it produces.Write safety
- Always approval-gated. Shopify mutations are force-gated at the registry level — a plan cannot mark one as pre-approved to skip the gate, and the irreversible or money-moving ones wait for a person even on a task or schedule you put on auto-approve.
- Never retried. A mutation is attempted exactly once. A retry after an ambiguous send would double-apply the change.
- Honest failure. Shopify answers HTTP 200 even when a write fails, tucking the reason into
userErrors. Every mutation must selectuserErrors { field message }up front, and any non-empty result is reported as a failure — never as a silent success. - Read-only stays read-only. The query gateway rejects mutation documents, and the mutation gateway rejects query documents, so neither can be used to sneak past the other's rules.
Use cases
These are goals you'd type into the Workspace with a Shopify store selected in the context picker. The read-only ones run immediately; the write ones plan the change and pause for your approval.
| Goal you'd type | What the agent does |
|---|---|
| "Give me the last 30 days of Shopify sales — daily revenue, AOV and top products." | Runs the aggregated sales summary and writes it up as a report, with the numbers computed server-side rather than re-added by the model. |
| "Join last month's Google Ads cost with Shopify order revenue and give me true ROAS per campaign." | Pulls Google Ads cost and Shopify revenue in the same run and reports blended ROAS off your real order data instead of platform-reported conversions. |
| "Which products sold nothing in 60 days but still have inventory?" | Cross-references the sales summary's top-products data with the admin product list and its live inventory counts. |
| "Find products missing a vendor or product type and list them." | Reads the admin product list — including drafts — and reports the gaps in your catalog metadata. |
| "Mark every out-of-stock product as draft." | Finds the matching products, then proposes one productUpdate mutation per product, each waiting for your approval. |
| "Raise the price of everything in the Summer collection by 10%." | Reads the collection, computes the new prices, and shows you the exact variant price mutations before any of them run. |
| "Who are my top 20 customers by lifetime spend, with their names?" | Reads the customer list sorted by amount spent (needs the read_customers scope). The names come back because your own request asks for them; the same list read by a schedule, an API key or a dashboard carries ids, order counts and totals only. |
| "Email me a Shopify sales report every Monday morning." | Turn the goal into a schedule — each fire re-reads live data, so the report is never stale. |
| "Build a cart with these three products and send me the checkout link." | Uses the anonymous storefront tools — no credentials needed — and returns a checkout URL for a human to complete. |
Troubleshooting
| Symptom | Fix |
|---|---|
| "This Shopify connection is storefront-only" | You connected with the domain alone. On the Integrations page, install the Shopify app (OAuth) — Connect store → Install from Shopify, nothing to type — or add an Admin token or client credentials under “Connect with an Admin API token from a custom app”, to unlock orders and admin data. |
| HTTP 401 / 403 from the Admin API | The token is invalid, revoked, or missing the scope for what you asked. Check the scope table above, add it in the custom app, reinstall, and reconnect. On a Shopify app (OAuth) connection, press Re-authorize on the store's row — a scope the app does not request yet is first added by the operator to the app's released version and to the scopes this deployment requests. |
| ACCESS_DENIED naming a scope | Shopify is telling you exactly which scope to tick — add it in the custom app's Admin API configuration and reinstall the app. On a Shopify app (OAuth) connection, the operator adds it to the app's released version and the scopes this deployment requests, then you press Re-authorize on the store's row (a typed write names the missing scope from the store's grant before it calls Shopify). |
| "Admin token expired" | Paste a fresh token on the Integrations page. Client-credentials connections refresh themselves and shouldn't hit this. |
| The app in your Shopify admin says “Installed — not linked to a workspace yet” | Click Connect to a workspace in the app inside your Shopify admin and sign in to Agent Planners — the store joins the workspace you have open. |
| A mutation was refused before it ran | The mutation document must select userErrors { field message }. The agent re-writes it and retries automatically when this happens. |
Frequently asked questions
- How do I generate a Shopify Admin API access token?
- In Shopify admin go to Settings → Apps and sales channels → Develop apps — since 2026 Shopify hands app creation off to its Dev Dashboard, and an existing custom app keeps working — configure the Admin API scopes you want (e.g. read_orders, read_products, write_products), save, then Install app and reveal the Admin API access token — it starts with shpat_. Paste it into the Shopify card on the Integrations page (Connect store → “Connect with an Admin API token from a custom app”) with your store domain — or skip the token and install the Shopify app (OAuth) from Shopify, with nothing to type.
- What scopes does Agent Planners need for Shopify?
- read_orders for orders, fulfillments and the sales summary, read_products for the admin product list and inventory, read_customers for customers, and read_inventory for stock levels. The typed tools add read_locations, read_discounts, read_returns and read_marketing_events; read_all_orders reaches orders older than 60 days (without it Shopify silently serves only the last 60), and ShopifyQL sessions and conversion rate need read_reports plus Shopify's Level 2 protected-customer-data approval. Add write_products / write_inventory / write_discounts (and write_pixels + read_customer_events for the app's web pixel) only if you want the agent to change the store — reads alone keep it strictly read-only. On the Shopify app (OAuth) you tick nothing: the consent screen carries exactly the scopes this deployment requests.
- Can the agent actually change my Shopify store?
- Yes, if your connection carries write scopes — ticked on a custom-app token, or granted on the Shopify app's consent screen when this deployment requests them. It reaches the Admin GraphQL mutation surface — create and update products, change prices, adjust inventory, manage collections and discount codes — but every mutation is force-gated: you see the exact document and variables and approve it before it runs (unless you put the task or schedule on auto-approve, which never covers the irreversible or money-moving ones), it's attempted only once, and a Shopify-side rejection is reported as a failure rather than a silent success.
- Do I need a token at all?
- No. The store domain alone connects the anonymous Storefront tier — catalog search, product details, cart building with a checkout link, and store policy search. Add a token, or install the Shopify app (OAuth) from Shopify, when you want orders, admin data or writes.
- Can the agent place an order or take payment?
- Not unless your connection carries order write scopes. No dedicated tool writes orders or takes payment — cart building returns a checkout URL and a human completes payment in their own browser. With write_orders or write_draft_orders on your token (or on the Shopify app's grant, when this deployment requests them), the generic mutation gateway can reach order mutations; the ones that move money — refunds (a return processed with a refund included), captures, cancellations, voids, completing a draft order, charging a saved payment method — and every delete always wait for a person, as does editing an order's line items. Creating an order, updating its notes, tags or addresses, or marking one as paid (which records a payment taken outside Shopify) takes the ordinary approval.
- Should I use a token, client credentials or OAuth?
- Use the Shopify app (OAuth) for the fastest setup — Install from Shopify, with no store domain to type and no custom app to build — its consent screen carries exactly the scopes this deployment requests (four reads by default; write scopes when the operator adds them). Use a custom-app Admin token when you want to choose the scopes yourself, write scopes included. Use client credentials if you'd rather not store a long-lived token (they're exchanged for a short-lived Bearer that refreshes itself). On every path, each store change goes through the approval step.
- Can I use my custom domain?
- For the token and client-credentials paths, yes — enter either your custom domain or the myshopify.com one. The Shopify app (OAuth) needs no domain at all: you install it from Shopify, which already knows the store.