Shopify
What does the Shopify Connection provide?
Follow our tutorials and learn how to connect Gadget and Shopify in just a few minutes!
- Gadget handles the OAuth process for merchants installing your application out of the box. See Shopify OAuth
- All objects in Shopify's API can be synced into your Gadget app as models. Connected models provide data access to any installing store's data, with no rate limit. Connected models can be extended in Gadget with additional fields to store extra information, though these fields will not sync back with Shopify by default.
- Gadget automatically registers webhooks for all Shopify API scopes you care about, mapping the events to your models to keep data in sync by running actions when webhooks are received. Actions can be used to react to changes within Shopify, make API calls back to Shopify to update data, or do anything else you can do with JavaScript.
- Gadget provides an easy-to-use API client for working with the Shopify API in backend code that manages rate limits and authentication. See Accessing the Shopify API
- Missed webhooks from bugs or infrastructure issues are recovered using a daily background sync, as per Shopify's recommended best practices. You can also manually sync your app to Shopify at any time or trigger syncs with the Sync API.
- Historical data (old products, orders, customers, etc) can be easily synced when a shop installs your app
- Gadget provides an embedded Shopify Admin frontend out of the box, as soon as you connect to Shopify in your development environment
- Gadget has easy-to-use facilities for billing your merchants
Currently, Gadget uses Shopify's 2024-10
API version for new connections.
Setting up the Shopify Connection
If you are looking to connect Gadget with Shopify, follow the Connecting to Shopify tutorial.
Available models
Gadget receives webhooks and syncs data from Shopify for the following models:
Model Name | Required Scopes | Webhook Topics |
---|---|---|
App | Always available | synced only |
App Credit | Always available | synced only |
Shopify App Credits (and other billing resources) are only available to OAuth apps created via the Shopify CLI or in the Shopify Partners dashboard that are marked for Public distribution. To successfully receive webhooks or sync this model, you must mark your app for Public distribution. Find more instructions in the Shopify docs. | ||
App Installation | Always available | synced only |
Company | read_customers | companies/create , companies/update , companies/delete |
Shopify Company and its related models are only available for apps installed on Shopify Partners Plus stores. To successfully sync and receive webhooks for these models, you must have access to a Shopify Partners Plus store. Access to these models also grant you access to special fields in Shopify Order and Shopify Draft Order models that are only available for Plus stores only. Find more information in the Shopify docs. | ||
Company Address | read_customers | Sent within Company Location model |
Company Contact | read_customers | company_contacts/create , company_contacts/update , company_contacts/delete |
Company Location | read_customers | company_locations/create , company_locations/update , company_locations/delete |
Company Contact Role | read_customers | synced only |
Company Contact Role Assignment | read_customers | synced only |
App Purchase One Time | Always available | app_purchases_one_time/update |
Shopify App Purchase One Time (and other billing resources) are only available to OAuth apps created via the Shopify CLI or in the Shopify Partners dashboard that are marked for Public distribution. To successfully receive webhooks or sync this model, you must mark your app for Public distribution. Find more instructions in the Shopify docs. | ||
App Subscription | Always available | app_subscriptions/update |
Shopify App Subscription (and other billing resources) are only available to OAuth apps created via the Shopify CLI or in the Shopify Partners dashboard that are marked for Public distribution. To successfully receive webhooks or sync this model, you must mark your app for Public distribution. Find more instructions in the Shopify docs. | ||
App Usage Record | Always available | synced only |
Blog | read_content | synced only |
Shopify blogs support Metafields but do not provide a REST or GraphQL mechanism for syncing them. Gadget does not support Metafields on Shopify Blog models. | ||
Article | read_content | synced only |
Shopify blog posts support Metafields but do not provide a REST or GraphQL mechanism for syncing them. Gadget does not support Metafields on Shopify Article models. | ||
Comment | read_content | synced only |
Theme | read_themes | themes/create , themes/update , themes/delete |
Gadget only syncs themes and assets that a store owns for each Shopify store, which excludes demo themes. Themes and assets for themes with role: "demo" in the Shopify API are not synced as API clients don't have permission to access individual asset values. | ||
Asset | read_themes | synced only |
Gadget syncs the Theme and Asset resources from Shopify using the REST API. Gadget does not sync the value column of the Asset resource. Syncing the value field can be done with a custom code effect, but Shopify requires one API call per asset to retrieve asset values, which often stresses Shopify API rate limits too much. Shopify Theme assets are often also quite large, including images and large JS files that are generally not important for applications to sync and store again.Gadget recommends avoiding syncing the Asset and Theme model if possible, and instead making API calls directly to Shopify to work with assets using the connections.shopify.current API client.Gadget only syncs themes and assets that a store owns for each Shopify store, which excludes demo themes. Themes and assets for themes with role: "demo" in the Shopify API are not synced as API clients don't have permission to access individual asset values. | ||
Balance Transaction | read_shopify_payments_payouts | synced only |
Checkout | read_checkouts , read_orders | checkouts/create , checkouts/update , checkouts/delete |
The read_checkouts scope will allow Gadget to process checkout related webhooks, but does not provide a mechanism to sync all existing checkouts. Adding the read_orders scope, while also including the Checkout model in your application, will result in all Abandoned Checkouts that aren't handled via webhooks (failed delivery, checkouts that already exist) being imported during nightly or manual syncs. | ||
Billing Address | read_checkouts , read_orders | Sent within Checkout model |
Checkout Applied Gift Card | read_checkouts , read_orders | synced only |
Checkout Line Item | read_checkouts , read_orders | Sent within Checkout model |
Checkout Shipping Rate | read_checkouts , read_orders | synced only |
Shipping Address | read_checkouts , read_orders | Sent within Checkout model |
Bulk Operation | Always available | bulk_operations/finish |
Carrier Service | read_shipping | synced only |
Cart | read_orders | carts/create , carts/update |
Cart Line Item | read_orders | Sent within Cart model |
Collection | read_products | collections/create , collections/update , collections/delete |
Gadget uses the Collection model to represent both Custom Collections and Smart Collections from Shopify. | ||
Collect | read_products | synced only |
Country | read_shipping | synced only |
Province | read_shipping | synced only |
Customer | read_customers | customers/create , customers/update , customers/delete |
Customer Address | read_customers | Sent within Customer model |
Customer Mergeable | read_customers | synced only |
Customer Payment Method | read_customer_payment_methods | customer_payment_methods/create , customer_payment_methods/update , customer_payment_methods/revoke |
Discount Code | read_discounts | synced only |
Discount | read_discounts | discounts/create , discounts/update , discounts/delete |
Discount Redeem Code | read_discounts | Sent within Discount model |
Discount Customer Gets Product | read_discounts | Sent within Discount model |
Discount Customer Buys Product | read_discounts | Sent within Discount model |
Discount Customer Gets Product Variant | read_discounts | Sent within Discount model |
Discount Customer Buys Product Variant | read_discounts | Sent within Discount model |
Discount Customer Gets Collection | read_discounts | Sent within Discount model |
Discount Customer Buys Collection | read_discounts | Sent within Discount model |
Dispute | read_shopify_payments_disputes | disputes/create , disputes/update |
Dispute data is only available for Shopify merchants using Shopify Payments. | ||
Dispute Evidence | read_shopify_payments_disputes | synced only |
Dispute File Upload | read_shopify_payments_disputes | synced only |
Dispute Evidence Fulfillment | read_shopify_payments_disputes | synced only |
Domain | Always available | domains/create , domains/update , domains/destroy |
Shopify Domain delete and update webhooks are missing key data, so Gadget does an inline sync of the Domain REST API resource when these webhooks arrive to properly discover updates and deletes. | ||
Draft Order | read_draft_orders | draft_orders/create , draft_orders/update , draft_orders/delete |
Draft Order Line Item | read_draft_orders | Sent within Draft Order model |
Draft Order Platform Discount | read_draft_orders | Sent within Draft Order model |
Draft Order Platform Discount Allocation | read_draft_orders | Sent within Draft Order model |
Order | read_orders | orders/create , orders/updated , orders/delete , orders/risk_assessment_changed |
Duty | read_orders | Sent within Order Line Item model |
Fulfillment Event | read_orders | fulfillment_events/create , fulfillment_events/delete |
Fulfillment | read_orders | fulfillments/create , fulfillments/update |
Fulfillment Line Item | read_orders | Sent within Fulfillment model |
Order Adjustment | read_orders | Sent within Refund model |
Order Line Item | read_orders | Sent within Order model |
Order Risk | read_orders | synced only |
Order Transaction | read_orders | order_transactions/create |
Refund Duty | read_orders | Sent within Refund model |
Refund | read_orders | refunds/create |
Refund Line Item | read_orders | Sent within Refund model |
Shipping Line | read_orders | Sent within Order model |
Tender Transaction | read_orders | tender_transactions/create |
Event | read_content , read_products , read_price_rules , read_orders | synced only |
File | read_files , read_themes , read_products | synced only |
This model tracks files uploaded by the merchant in the Files section of the Shopify Admin. Shopify doesn't expose webhooks for the File resource, so files are only updated in Gadget on sync. Files can be accessed via the read_files or read_themes scopes. | ||
Fulfillment Order | read_assigned_fulfillment_orders , read_merchant_managed_fulfillment_orders , read_third_party_fulfillment_orders | fulfillment_orders/order_routing_complete , fulfillment_orders/fulfillment_request_submitted , fulfillment_orders/fulfillment_request_accepted , fulfillment_orders/fulfillment_request_rejected , fulfillment_orders/placed_on_hold , fulfillment_orders/cancellation_request_submitted , fulfillment_orders/cancellation_request_accepted , fulfillment_orders/cancellation_request_rejected , fulfillment_orders/cancelled , fulfillment_orders/fulfillment_service_failed_to_complete , fulfillment_orders/moved , fulfillment_orders/split , fulfillment_orders/merged , fulfillment_orders/hold_released , fulfillment_orders/line_items_prepared_for_local_delivery , fulfillment_orders/line_items_prepared_for_pickup , fulfillment_orders/rescheduled , fulfillment_orders/scheduled_fulfillment_order_ready |
Fulfillment Order Line Item | read_assigned_fulfillment_orders , read_merchant_managed_fulfillment_orders , read_third_party_fulfillment_orders | synced only |
Fulfillment Service | read_fulfillments | synced only |
GDPR Request | Always available | shop/redact , customers/redact , customers/data_request |
This model tracks incoming GDPR webhook requests from Shopify to delete merchant or customer data. These GDPR webhooks are required to be supported by Public applications for the Shopify app store, which you can read more about in the Shopify Docs. This model doesn't correspond to an API endpoint within Shopify. | ||
Gift Card | read_gift_cards | synced only |
This model tracks issued gift cards for a Shopify store. Shopify only allows access to the read_gift_cards scope on Shopify Plus stores, and only for Custom apps provisioned within the Shopify Admin.Shopify doesn't offer gift card webhooks, so gift card data is only refreshed on sync. | ||
Inventory Item | read_inventory | inventory_items/create , inventory_items/update , inventory_items/delete |
Inventory Items are synced using the REST API endpont for Inventory Levels for each Location to get a list of inventory levels, and then using the REST API endpoint to get a list of inventory items for each level. | ||
Inventory Level | read_inventory | inventory_levels/connect , inventory_levels/update , inventory_levels/disconnect |
Inventory Levels are synced using the REST API endpoint for Inventory Levels at a Location. | ||
Location | read_locations | locations/create , locations/update , locations/activate , locations/deactivate , locations/delete |
Market | read_markets | markets/create , markets/update , markets/delete |
Market Region | read_markets | Sent within Market model |
Market Web Presence | read_markets | Sent within Market model |
Page | read_content | synced only |
Shopify pages support Metafields but do not provide a REST or GraphQL mechanism for syncing them. Gadget does not support Metafields on Shopify Page models. | ||
Payout | read_shopify_payments_payouts | synced only |
Price Rule | read_price_rules | synced only |
Product | read_products | products/create , products/update , products/delete |
Product Image | read_products | Sent within Product model |
This model has been deprecated. Read more about ProductImage deprecation. | ||
Product Media | read_products | Sent within Product model |
Product Option | read_products | Sent within Product model |
Product Variant | read_products | Sent within Product model |
Product Variant Media | read_products | Sent within Product Variant model |
Redirect | read_content | synced only |
Script Tag | read_script_tags | synced only |
Shop | Always available | shop/update , app/uninstalled |
Selling Plan Group | read_products | selling_plan_groups/create , selling_plan_groups/update , selling_plan_groups/delete |
Selling Plan Group Product | read_products | Sent within Selling Plan Group model |
Selling Plan Group Product Variant | read_products | Sent within Selling Plan Group model |
Selling Plan | read_products | Sent within Selling Plan Group model |
Subscription Contract | read_own_subscription_contracts | subscription_contracts/create , subscription_contracts/update |
Subscription Billing Attempt | read_own_subscription_contracts | subscription_billing_attempts/success , subscription_billing_attempts/failure , subscription_billing_attempts/challenged |
Subscription Line | read_own_subscription_contracts | synced only |
Subscription Manual Discount | read_own_subscription_contracts | synced only |
Business Entity | Always available | synced only |
Payments Account | read_shopify_payments_accounts | synced only |
Deprecated shopifyProductImage
model
Product image records in Shopify no longer belong to a single product, a single image can be referenced by multiple products. Because of this change, syncing shopifyProductImage
data in Gadget may result in unexpected and non-deterministic updates to the relationship field on shopifyProductImage
records when an image is shared between multiple products.
To address this, Gadget has introduced the shopifyProductMedia
and shopifyProductVariantMedia
models that sync all product and product variant related media including images, videos, 3D models, and files. We recommend using shopifyProductMedia
and shopifyProductVariantMedia
models and have marked shopifyProductImage
as deprecated.
If you have any questions, please get in touch with the Gadget staff on Discord.
Troubleshooting
The sync between Shopify and my Gadget app failed.
Do you have any custom code running within the create
action on the Shopify Sync model? A custom action with errors will prevent the sync from completing successfully. Try removing or editing the code within actions and running a manual sync.
Actions aren't updating my records in Shopify.
You need to explicitly call out to the Shopify client in your action to manipulate data in Shopify. See accessing the Shopify API.
Webhooks aren't being registered with Shopify.
If you see that some webhooks aren't being registered even after clicking Register Webhooks on the Installs page, it is possible that your app has not requested access to Protected Customer Data. See here for more details.
Frequently asked questions
How do I make calls back to Gadget from a Shopify storefront?
You can call your Gadget app's API client in the storefront's Shopify theme. To do so, you can use the Direct Script Tag option in the Installation section of your app's API Reference.
How do I make an embedded Shopify app using Gadget?
Gadget supports being used as a backend for an app embedded in the Shopify Admin. You can read the docs for setting up the Gadget app client and Provider and go through the tutorial that walks you through setting up an embedded app with the Shopify CLI and Gadget.
When does Gadget automatically sync my Shopify Connection?
Gadget will fully sync your Shopify Connection on demand when you request a sync from the Connections view. Gadget will also automatically fetch all recent data from Shopify in the background in a scheduled daily sync. To see when your app was last synced with Shopify, you can visit the Connections view or view the Shopify Sync data editor.
Building Shopify apps using the Gadget connection
For more information on how to build Shopify apps using the Gadget Shopify connection, check out our guide here.