Overview
A client-mode connector for the Shopify GraphQL Admin API (version2026-10). Use it to connect the shop floor to your online store: when a counter or scale reports finished goods, adjust the sellable stock in Shopify, and push the list of open, unfulfilled orders to MQTT so a packing line or pick-to-light system can work through it.
Every GraphQL event is a POST to /admin/api/2026-10/graphql.json. The event only decides the MQTT topics; the GraphQL document and its variables travel in the payload as body. Canonical bodies for each event are below.
Topics use
finance/shopify/<object>/<verb>; replies land on <topic>/response. Set BASE_ADDRESS to your store’s permanent https://<store>.myshopify.com domain (not a custom storefront domain).
See the base guide: REST API Connectors.
Auth: every GraphQL call sends the
X-Shopify-Access-Token header with access_token from the payload. Get a token in one of these ways:- Dev Dashboard app, client credentials. Create an app in the Dev Dashboard in the same Shopify organisation as the store, install it with the scopes below, and publish its client id and secret to ClientCredentialsToken. The token lasts 24 hours (
expires_in86399). This only works for stores in your own organisation; other stores answershop_not_permitted. - Existing admin-created custom app. Its
shpat_…Admin API access token does not expire. New admin-created custom apps can no longer be made. - Public or custom-distribution app. Run the authorization code grant outside the broker and pass the token.
read_orders, read_inventory, write_inventory, read_locations and read_products. Keep credentials in Hub secrets (suggested names SHOPIFY_STORE, SHOPIFY_CLIENT_ID, SHOPIFY_CLIENT_SECRET, SHOPIFY_ACCESS_TOKEN). Never commit them into the .lot.Basic Syntax
MQTT examples
Get a token (client credentials)
Publish tofinance/shopify/oauth/token:
finance/shopify/oauth/token/response: {"access_token":"…","scope":"read_inventory,write_inventory,…","expires_in":86399}.
Find the inventory item for a SKU
Publish tofinance/shopify/inventory-item/list:
available and on_hand quantities. Use these ids in the adjustment. GetLocations lists all locations ({"query":"query Locations($first: Int!) { locations(first: $first) { nodes { id name isActive } } }","variables":{"first":20}}).
Adjust stock from a sensor count
Publish tofinance/shopify/inventory/adjust (here: 5 finished units counted on line 3):
delta is the change, not the new total. Use a negative delta to remove stock. reason must be one of Shopify’s reasons, for example correction, cycle_count_available or received. referenceDocumentUri shows up in the store’s inventory history, so point it at your own system (gid://coreflux/…). A good reply has "userErrors": [] and quantityAfterChange for each change.
Publish the pick list
Publish tofinance/shopify/order/list:
pageInfo.hasNextPage is true, publish again with "after" set to pageInfo.endCursor. read_orders only reaches recent orders; older ones need the read_all_orders scope.
Smoke test
Publish tofinance/shopify/shop/get:
Keeping the token
Client-credentials tokens last 24 hours. These two actions fetch a new one from Hub secrets twice a day and store it:finance/shopify/# topics with a rule, because these payloads carry tokens and client credentials.
Webhooks (companion, not packaged)
Shopify canPOST an orders/create webhook to an HTTPS URL. Each delivery carries X-Shopify-Hmac-SHA256, a base64 HMAC-SHA256 of the raw body made with the app’s client secret, and should be rejected if it does not match. A REST API connector in server mode cannot check that signature, so the receiver is not part of this template. Options: put a verifying proxy in front of a separate ENABLE_SERVER connector, use Shopify’s Amazon EventBridge or Google Cloud Pub/Sub delivery, or poll GetOrders on a timer (for example with created_at:>… in q).
Notes
- API versions are released every quarter and each is supported for at least 12 months.
2026-10is accessible until October 2027. Change the version in eachENDPOINTwhen you upgrade; a retired version is answered by the oldest supported one. - Rate limits use a calculated query cost in a leaky bucket per app and store; the size and restore rate depend on the store’s plan. Each reply carries
extensions.cost. OnTHROTTLED, wait and retry with the same idempotency key. - Common errors: 401
[API] Invalid API key or access token(bad or expired token),ACCESS_DENIEDinerrors(missing scope),userErrorssuch asCHANGE_FROM_QUANTITY_STALEor an invalid reason, 404 (wrong store domain). - Not covered: the REST Admin API (legacy), bulk operations, product and fulfillment mutations,
inventorySetQuantities(sets an absolute quantity). - Suggested branches:
feat/rest-api-route-shopify,feat/docs-rest-api-shopify(Hugo pushes).

