Skip to content
Browse the documentation
Connectors

Shopify

What the Shopify connector reads, with which permissions, what it never touches, how it syncs, and the facts it produces.

Last changed Markdown versionllms.txt

Source module: app/connectors/shopify.py. Kind: facts only. Display name: "Shopify".

The order system in the flagship refund story: the agent refunds in Stripe and the order must show as cancelled here. The connector reads orders changed since the watermark through the Admin GraphQL API and turns each into a state fact plus event facts, keyed by the order's numeric id, which is what an agent's tools see.

Auth and scopes

Item Value
Method Admin API access token of a custom app, sent as X-Shopify-Access-Token, against https://{shop}/admin/api/{version}/graphql.json (version 2026-07; override with api_version in the credentials)
Credentials stored (encrypted) shop (the *.myshopify.com domain), access_token; optional api_version
Least-privilege scopes read_orders. Add read_customers only if you want customer identities hashed for cross-system linking; without it Shopify refuses the customer field with ACCESS_DENIED, the connector sends the orders query again without it, customer_hid is null, and the connection's health says so. Nothing else.
Connection test { shop { name myshopifyDomain } }
How to get the token Settings → Apps and sales channels → Develop apps → Create an app → Configure Admin API scopes (read_orders) → Install app → Reveal the Admin API access token once

Fields pulled and why

One query, orders(first: 100, after, query: "updated_at:>='<watermark>'", sortKey: UPDATED_AT), paged by cursor:

Field Used for
legacyResourceId, id, name Subject id (numeric order id), order_name attribute
createdAt, updatedAt State fact timestamp, watermark
cancelledAt, cancelReason order_cancelled fact
displayFinancialStatus, displayFulfillmentStatus State attributes and the derived status
customer.email HMAC-hashed into customer_hid; the email is discarded
refunds { id createdAt totalRefundedSet { shopMoney { amount currencyCode } } } refund_created facts
fulfillments { id createdAt status } fulfillment_created facts

Line items, addresses, names, phone numbers, notes, payment details and metafields are never requested.

Fact types produced

Subject id is the numeric order id (10231), subject kind order.

fact_type When Attributes raw_ref
order_status Every order returned (one per updatedAt) status (open, cancelled, refunded, partially_refunded), financial_status, fulfillment_status, order_name, customer_hid shopify:order:{id}:status:{updatedAt}
order_cancelled cancelledAt set reason, customer_hid shopify:order:{id}:cancelled
refund_created Each refund on the order amount (major units), currency, customer_hid shopify:refund:{refund_id}
fulfillment_created Each fulfilment status shopify:fulfillment:{fulfillment_id}

status is derived from fields Shopify reports and nothing else: cancelled when cancelledAt is set, else the refund state from the financial status, else open. The library refund_workflow template's precondition state_before_action: {source: shopify, type: order_status, where: {status: eligible}} is a placeholder for your own policy: with this connector write it against the real fields, for example where: {financial_status: paid} or where: {status: open}.

Incremental sync, watermark, throttling

  • First sync reads every order; later syncs add updated_at:>='<watermark>'. The watermark is the newest updatedAt seen, then advanced to the sync time less the safety margin like every connector.
  • Shopify throttles GraphQL by query cost with HTTP 200 and a THROTTLED error; the connector backs off and retries up to six times. HTTP 401/403 marks the connection for re-authentication.
  • Upserts are idempotent on raw_ref; a re-sync changes nothing that did not change.

Claims produced

None.

Limitations

  • Orders only. Draft orders, returns (as distinct from refunds), inventory and customer records are not read.
  • refund_created carries the refund's total; per-line refund detail is not read.
  • Orders archived or deleted in Shopify stop appearing in updated_at queries; facts already written remain.