Skip to content
GitHub
Get started →

Shopify adapter

The Shopify adapter queries the Shopify Storefront API (GraphQL). It exposes four source types as Spelo collections:

sourceWhat it returns
productsAll published products (name, description, price, images, variants)
collectionsMerchandising collections (title, handle, products list)
articlesBlog articles
pagesStatic pages

The most common setup is one collection mapped to products.

Config shape

{
"type": "shopify",
"config": {
"shopDomain": "acme-store.myshopify.com",
"storefrontAccessToken": "1234567890abcdef1234567890abcdef",
"apiVersion": "2024-10"
},
"collections": {
"products": {
"source": "products",
"searchable_fields": ["title", "description", "tags"],
"filterable_fields": ["productType", "vendor", "tags"],
"display_fields": ["id", "title", "price", "image"],
"description": "All in-stock products in our Shopify store"
}
}
}

Setup

  1. Enable the Storefront API

    Shopify admin → SettingsApps and sales channelsDevelop appsAllow custom app development.

    Click Create an app → name it SpeloConfigure Storefront API scopes.

  2. Choose scopes (all read-only)

    • unauthenticated_read_product_listings
    • unauthenticated_read_product_inventory
    • unauthenticated_read_product_tags
    • unauthenticated_read_content
    • unauthenticated_read_collection_listings
  3. Install the app and copy the Storefront Access Token

    Click Install app, then copy the Storefront access token (32-character hex string). This is the storefrontAccessToken.

  4. Find your shop domain

    It’s the *.myshopify.com form — not your custom domain. Find it in admin → SettingsDomains.

  5. Paste in the dashboard

    Dashboard → DataShopify → paste shop domain + token → Test connection.

Storefront API is public

The Storefront Access Token is explicitly designed to be public — it only exposes what your online store already exposes. It is not like an admin API key. Leaking it only gives an attacker access to publicly visible product data. That’s why the adapter validates the token format (32-char hex) but doesn’t treat it as high-sensitivity.

Do not paste an Admin API key here. Those have write scopes. Shopify’s Admin token (starts with shpat_) is rejected by the adapter.

Operator translation

Shopify’s Storefront API uses a distinctive query language. The adapter translates filters:

FilterShopify query fragment
title contains footitle:*foo*
productType eq shoesproduct_type:shoes
vendor eq nikevendor:nike
tags contains newtag:new
free-text querytitle:*Q* OR description:*Q* OR tag:*Q*

Sorting uses sortKey: TITLE, PRICE, CREATED_AT, UPDATED_AT, BEST_SELLING.

What comes back

Each product is returned with these fields (display-ready):

{
id, handle, title, description,
productType, vendor, tags,
price: { amount, currencyCode },
image: { url, altText },
variants: [{ id, title, availableForSale, price }]
}

Use display_fields to cut this down if you want faster responses.

Pagination

The Storefront API uses cursor pagination. Spelo always takes the first N (up to max_limit, capped at 10). Voice is a short-form interface — no one wants 50 items read to them.

Security notes

  • Storefront Access Token is public-safe (Shopify’s design).
  • The adapter emits only query { products { ... } } — no mutations possible. customer, checkout, and checkoutCreate are never called.
  • Admin API is never used. Your admin account is untouched.

OAuth alternative

If you don’t want to mess with the Storefront API, use the OAuth flow. Same end result, less manual setup.

Troubleshooting

  • 401 Unauthorized → wrong token, or the app wasn’t installed. Go back to Apps → Develop apps → Install app.
  • 400 Storefront API access disabled → your shop’s plan doesn’t include Storefront API access. Every modern plan does; contact Shopify support if you see this.
  • No products returned — check that you selected unauthenticated_read_product_listings and there are published products. Draft products are invisible to the Storefront API.
  • CORS error from the browser during setup — this is server-side; the error must be coming from the dashboard, not the widget. Contact support.

More: Database connection errors.