Knowledge & tools

Shopify tool

The Shopify tool lets an agent manage a Shopify store through the GraphQL Admin API - products and variants, inventory, collections, tags and metafields, orders, fulfillment with tracking, refunds, draft orders, customers, and discount codes. One tool configuration maps to one store. The agent picks one of 39 actions per call; it never writes GraphQL itself. Set it up once as a tool configuration, then assign it to a bot.

This tool changes a real store. It can update prices and inventory, cancel orders, issue refunds, and delete products, collections and customers. Connect a store you control, grant only the scopes the agent needs, and read Safety in autonomous runs before scheduling a bot that manages the store on its own.

Mental model

One store per configuration, one action per call. Shopify retired static admin tokens for new apps, so a modern connection is Store domain + Client ID + Client Secret from an app the merchant creates in the Shopify Dev Dashboard. Hania exchanges those for short-lived (24 h) access tokens automatically and invisibly - you never see or manage a token. A static Access token field exists only as a legacy fallback for older custom apps created inside the Shopify admin. Prefer Client ID + Secret; use the token only if that's the app you already have.

What it can do

The agent chooses one action per call. The 39 actions, by area:

  • Store - get_shop, list_locations.
  • Products - list_products, get_product, create_product, update_product, delete_product, update_variant.
  • Inventory - set_inventory (absolute) and adjust_inventory (delta), per location.
  • Collections - list_collections, create_collection, delete_collection, add_to_collection, remove_from_collection.
  • Tags & metafields - add_tags, remove_tags (product / order / customer), set_metafield.
  • Orders - list_orders, get_order, update_order, mark_order_paid, close_order, open_order, cancel_order.
  • Fulfillment & refunds - create_fulfillment, update_tracking, create_refund.
  • Draft orders - list_draft_orders, create_draft_order, complete_draft_order, delete_draft_order.
  • Customers - list_customers, get_customer, create_customer, update_customer, delete_customer.
  • Discounts - create_discount, delete_discount.

Before you start

You need:

  • A Shopify store (its address ends in .myshopify.com).
  • Access to the Shopify Dev Dashboard (dev.shopify.com/dashboard).
  • The Develop apps permission on the store (a store owner has this; staff need it granted).

Note: custom apps can no longer be created inside the Shopify admin itself - the Dev Dashboard is the only path for new apps. From the store admin you can reach it via Settings → Apps → Develop apps → "Build apps in Dev Dashboard".

Connect a store

  1. Create an app. In the Shopify Dev Dashboard, choose Create app and give it any name (e.g. "Hania Integration").
  2. App URL. App creation asks for an app URL. A token-only integration has no hosted app, so any URL you control (for example your own website) is fine here - the agent never uses it.
  3. Grant scopes. In the app version's Access section, add read + write scopes for what the agent should do. The full capability set is read + write for Products, Orders, Draft orders, Customers, Inventory, Locations, Fulfillment, Discounts, and Metafields / Metaobjects. Fewer scopes are fine - actions the app can't perform fail with a clean permissions error the agent reports.
  4. Declare protected customer data. Find the Protected customer data access section in the app's settings and declare access to customer data plus the name, email, phone and address fields. For your own store's app this takes effect immediately, with no review. See the callout below - this is the step people miss.
  5. Install the app on the store: in the Dev Dashboard, open the app → InstallsInstall app → choose the store → Install.
  6. Copy credentials. Open the app's Settings page and copy the Client ID and Client secret. Paste them into the Hania tool form together with the store's *.myshopify.com domain, and save.
Don't skip step 4 - protected customer data. This is the single most common setup mistake. Until you declare protected customer data access (name, email, phone, address), every Customer and Draft order action fails with ACCESS_DENIED: This app is not approved to access the Customer object, even though products and orders work fine. Declaring it on your own store's app is instant - no Shopify review required.
Shopify updates the Dev Dashboard from time to time, so treat the section names above as authoritative and the exact button labels and menu positions as approximate - find the named section if a label has moved.

Legacy connection (static token)

If the merchant already has a custom app created inside the Shopify admin, its static Admin API access token (starts with shpat_) still works. Paste it into the Admin API Access Token field instead of the Client ID + Secret, along with the store domain. These tokens can't be rotated - only uninstalling and reinstalling the app regenerates one. New stores should use the Client ID + Secret path above; the token field is legacy-only.

Field reference

The tool configuration has five fields. Only the store domain is strictly required; you must then supply either Client ID + Client Secret or an Access Token.

  • Store Domain (required) - your store's myshopify.com address, e.g. my-store.myshopify.com. The plain store name also works. Custom domains are rejected - it must be the *.myshopify.com address.
  • Client ID - from your app's Settings page in the Shopify Dev Dashboard. Used together with the Client Secret.
  • Client Secret (secret) - from the same Settings page. Hania exchanges it automatically for short-lived access tokens; stored encrypted and never shown again after saving.
  • Admin API Access Token (secret, legacy apps only) - only for older custom apps created in the Shopify admin with a static shpat_ token. Leave blank when using Client ID + Secret.
  • API Version (optional, default 2026-07) - advanced. The Shopify Admin API version. Leave the default unless you know you need another.

What the agent can and cannot do

Beyond the actions above, a few behaviors are worth knowing:

  • Search & limits - list actions accept Shopify search syntax in query (tag:vip, status:draft, email:[email protected]) and return up to 50 results per call. Shopify's search index lags writes by a few seconds, so the agent re-reads fresh records by id after a change.
  • Inventory is per location - single-location stores just work; on multi-location stores the agent lists locations and picks (or asks) which one to set.
  • Some changes are asynchronous - collection add/remove and order cancellation return a job and land a moment later on Shopify's side.
  • Prices are decimal strings in the store currency; discounts are percentage-off (1-100).
  • Deleting a customer with orders is refused by Shopify - expected, and surfaced cleanly rather than as a crash.

Some limits are enforced by the backend, so they're safe to rely on: the agent never captures payments (completing a draft order always leaves it payment-pending; marking an order paid is a separate, explicit action), never permanently deletes orders (there is no raw-GraphQL passthrough and no hard order-delete action), and never emails customers unless explicitly told to - fulfillment and cancellation notifications are off by default.

Troubleshooting

  • "access-token exchange failed" - the wrong store domain, wrong Client ID / Secret, or the app isn't installed on that store. Client-credentials only works for an app in the store's own organization, so re-check steps 5 and 6 of Connect a store.
  • ACCESS_DENIED on customers or draft orders - the protected customer data declaration (step 4) was skipped. Declare it and retry.
  • ACCESS_DENIED on any other action - the matching scope wasn't granted in step 3. Add the scope in the app's Access section.
  • Store domain rejected - it must be a *.myshopify.com address; custom domains fail validation with a clear message.
  • THROTTLED (429) - Shopify rate-limited the request; the agent backs off and retries.
  • SHOP_INACTIVE (403) - the store is paused or closed on Shopify's side.
  • "shopify rejected the request: field.path: message" - a validation error; the agent auto-corrects these, so they may flash through a trace transiently before the call succeeds. Error text comes verbatim from Shopify.

Safety in autonomous runs

Like any tool, the Shopify tool carries a safety classification (read-only / destructive / sends-data-externally) that governs scheduled or triggered (autonomous) runs. Because this tool can delete products, collections and customers and cancel orders, a new configuration is created with Read-only switched off, Destructive switched on, and Sends data externally on - so destructive actions are gated in autonomous runs unless the bot's "Allow destructive actions in autonomous runs" is enabled. Keep those defaults, and prefer the tighter control: grant the app only the scopes the agent needs, so a limit is enforced by Shopify rather than only by an app-layer flag. Interactive chat is never gated by these flags.

Security

The Client Secret and any static access token are stored AES-encrypted at rest and are never returned by the API - the console shows only whether each is set. Hania exchanges the Client Secret for short-lived 24 h tokens behind the scenes; those aren't exposed either. Editing a configuration without retyping a secret preserves the stored one, so you must retype it to replace it.

Blueprint

The fastest way to a working store agent is the Shopify Store Manager blueprint (e-commerce category) - a pre-built agent wired for store management. Pick it from the blueprint gallery when creating a bot; the only thing you supply is the Shopify credential from this guide, and the rest of the agent is configured for you.