Scopes & Permissions Reference
Two layers of scoping protect your store: Shopify OAuth scopes (what the app itself may access) and Shopigent category toggles (what your agents may access). An agent can never exceed either layer.
Category → Shopify scope map
| Shopigent category | Read scope | Write scope |
|---|---|---|
| Products | read_products |
write_products |
| Orders | read_orders |
write_orders |
| Customers | read_customers |
write_customers |
| Discounts | read_discounts |
write_discounts |
| Content (pages/blogs) | read_content |
write_content |
| Metaobjects & Custom Data | read_metaobjects |
write_metaobjects |
| Theme Pull Requests | app-internal GitHub repository connection | app-internal GitHub repository connection |
| Files / Media upload | read_files (required) |
write_files (required) |
| Inventory | read_inventory |
write_inventory |
| Fulfillments | read_fulfillments |
write_fulfillments |
| Translations (Pro) | read_translations |
write_translations |
| Publications | read_publications |
write_publications (optional) |
Optional publication access
read_publications remains part of Shopigent's required read access. The separate write_publications scope is optional and lets Shopigent publish or unpublish resources on a sales channel selected by the user. It is not required for the rest of the tool catalog: product, order, content, media, and other enabled tools continue to work when publication access is not granted.
To enable it, open Scopes & Permissions in the embedded app, find Product publication management, and choose Enable product publication management. Shopify then asks the merchant to approve this scope. The embedded app reports the verified live grant; declaring the optional scope in app configuration does not grant it. A merchant may decline the request or later choose Revoke publication access without disabling the other tools.
Publication targets are always selected explicitly from the IDs and channel labels returned for that store. Shopigent does not infer a channel from its name, choose an "Online Store" automatically, or publish to every channel.
Shopigent does not request Shopify's direct theme scopes. Theme repository
work uses the four github_* tools. When the GitHub App is configured and this shop already has a stored installation, the page can choose a repository that installation can access. Starting a new GitHub App connection on that page is unavailable; the page then says to use a repository-scoped personal access token. If the GitHub App is not configured, the page says the one-click flow is not set up and the token form remains. Shopigent reads
explicit files. A dry-run returns a preview and does not open a pull request. A live
call requires confirmation, then can create a branch,
commits, and a pull request. It never merges, deploys, publishes, or edits theme
code through the Admin Theme API. After the merchant merges, Shopify's native
GitHub theme integration can synchronize that connected branch to the
merchant-selected theme; use an unpublished theme for review so the live
storefront remains unchanged.
File scopes for media upload
upload_product_media requires a verified live grant containing
write_products, read_files and write_files. A configured or stored scope
string is never proof of authorization — only a live OAuth grant snapshot counts.
read_files and write_files are declared as required scopes in the app
configuration. Together they cover the staged upload workflow:
- stagedUploadsCreate — request signed upload targets from Shopify.
- Binary upload — PUT each file to its signed target.
- fileCreate — register the uploaded files as Shopify MediaImage records.
- File-status polling — wait for Shopify to process each image to READY.
- productSet (attach) — attach images to a product in gallery order and set the featured index.
A verified live grant of both read_files (file-status polling) and
write_files (staged upload + registration) is required; requesting one without
the other is not enough.
Four dashboard states (never conflated)
Shopigent's embedded app distinguishes four layers that the dashboard surfaces separately:
| Layer | Means | Example state |
|---|---|---|
| Tool enabled | The merchant toggled upload_product_media on in Curated Tools |
Checkbox == on |
| Requested | The app configuration declares read_files and write_files |
Process.env.SCOPES includes both |
| Granted | The store's live Shopify installation actually granted read_files and write_files |
Verified OAuth snapshot |
| Executable | All four layers satisfied | Green badge: "Media upload is available" |
When the live grant is stale or unverifiable, the dashboard shows
"Reauthorization required" and an exact list of missing scope handles
(read_files, write_files, write_products) rather than a vague "access" label.
An enabled toggle is never proof of Shopify authorization — a store may have
the tool on but the scope not yet granted.
See the Troubleshooting guide for
steps to resolve a MISSING_SCOPE error.
How the layers interact
Agent calls tool
│
├─ 1. Is this tool enabled for the shop? ── no → not included in tools/list
├─ 2. Does the plan allow this live call? ── no → error, upgradeRequired: true
│ A curated dry-run on a plan that cannot run the write still previews
│ and does not write. Custom tools, including a dry-run, require Pro.
├─ 3. Is the scope category enabled and granted? ── no → the call does not run
├─ 4. Confirmation on, or one of the four actions ── yes, and this is not a dry-run
│ that always pause? → confirmation_pending
└─ 5. Execute → record in the audit log
Principle of least privilege
- Start with only the categories you need. You can enable more later without reinstalling.
- There is one connection key per store. Regenerating it rejects the previous key for every client.
- Review the audit log after enabling a new category to see how your agent uses it.