← Blog

How to Build a Claude-Powered Chatbot for Shopify

2026-11-05 · 5 min read · SubToAPI Team

Building a Claude-powered chatbot for Shopify means connecting Claude's language model to your store's storefront or admin, so it can answer product questions, check order status, and handle customer support in natural language. The core work is three pieces: a Shopify app or theme extension that captures customer messages, a backend that calls Claude with store context (products, policies, order data), and a way to return Claude's response to the shopper in a chat widget.

This guide walks through the architecture, the Shopify-specific details (webhooks, Storefront API, app embeds), and the Claude integration itself, including why most teams skip building their own Claude auth layer and use a hosted API gateway instead.

Architecture Overview

A production Shopify chatbot typically has four layers:

  1. Chat widget — embedded in the theme via an app block or script tag, handles the UI
  2. Backend endpoint — receives messages, builds the prompt, calls Claude, streams the reply
  3. Shopify data layer — Storefront API for products, Admin API for orders/customers
  4. Claude API access — the model that generates responses

The tricky part isn't the chat UI — it's steps 3 and 4 working together reliably without leaking customer data or blowing your API budget on every page load.

Step 1: Set Up a Shopify App (or Theme App Extension)

If you're shipping this as an installable app, scaffold it with the Shopify CLI:

npm init @shopify/app@latest
cd my-claude-chatbot
shopify app dev

For a lighter approach, add a theme app extension that injects a chat widget into the storefront without requiring merchants to edit theme code manually. The extension just needs a container div and a script that posts messages to your backend.

Step 2: Pull Relevant Store Context

Claude gives better answers when it has real store data, not just a generic system prompt. Two sources matter most:

A minimal product fetch:

const query = `
  query getProduct($handle: String!) {
    productByHandle(handle: $handle) {
      title
      description
      variants(first: 5) {
        edges { node { price { amount } availableForSale } }
      }
    }
  }
`;

const res = await fetch(`https://${shop}.myshopify.com/api/2024-01/graphql.json`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Shopify-Storefront-Access-Token": storefrontToken,
  },
  body: JSON.stringify({ query, variables: { handle: "classic-tee" } }),
});

You don't need to fetch your entire catalog on every message. A common pattern is to do a quick keyword or vector match first to find the 1-3 products relevant to the customer's question, then pass only those into the Claude prompt.

Step 3: Call Claude with Store Context

Once you have the relevant product or order data, build a system prompt that gives Claude its role, tone, and the specific data it needs for that turn:

const response = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "claude-opus-4",
    max_tokens: 500,
    system: `You are a support assistant for Acme Apparel.
Only answer using the product data provided below. If unsure, offer to connect the customer with a human.

Product context:
${JSON.stringify(productData)}`,
    messages: [{ role: "user", content: customerMessage }],
  }),
});

const data = await response.json();

Using SubToAPI here means you don't have to build your own Claude auth and rate-limiting layer — you get a sub_live_... application key, usage metadata per request, and streaming support out of the box. For a chatbot that runs across many storefront sessions, usage metadata matters: you can see exactly how many tokens each conversation costs and set per-plan limits before it eats your margin. Full request/response details are in the docs and messages reference.

Step 4: Stream Responses to the Chat Widget

Shoppers expect chat replies to appear incrementally, not all at once after a 3-second pause. Claude supports streaming, and so does SubToAPI — set "stream": true and consume server-sent events on the frontend:

const res = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "claude-opus-4",
    max_tokens: 500,
    stream: true,
    messages: [{ role: "user", content: customerMessage }],
  }),
});

const reader = res.body.getReader();
// read chunks and append tokens to the chat bubble as they arrive

See /docs/streaming for the full event format and reconnection handling.

Step 5: Handle Order Lookups and Tool Use

For "where's my order" type questions, Claude needs to call out to Shopify's Admin API mid-conversation rather than guessing. This is where tool use (function calling) comes in: you define a lookup_order tool, Claude decides when to invoke it, your backend executes the actual Admin API call, and the result goes back to Claude to compose the final answer. This keeps Claude from hallucinating tracking numbers and keeps order data server-side instead of in the prompt. Details on defining and handling tools are at /docs/tools.

Step 6: Guardrails for a Storefront Bot

A few things matter more on a live storefront than in an internal tool:

Getting Started Quickly

If you want to skip building Claude authentication, retries, and rate-limit handling yourself, sign up for a free trial, grab a sub_live_... key, and follow the quickstart to get your first message through in under ten minutes. Pricing starts at €9/month for solo projects, with team seats at €19 and higher-volume Scale plans at €49 — check /pricing for details.

Questions

Does the chatbot need Shopify Plus? No. Theme app extensions and the Storefront/Admin APIs work on all Shopify plans; Plus only matters if you need checkout-level scripting beyond chat.

Can Claude see real inventory and order data? Only if your backend fetches it and passes it into the prompt or exposes it via a tool — Claude has no direct access to your store, which keeps data under your control.

How do I control API costs as chat volume grows? Cap max_tokens, trim unnecessary product context, and track per-conversation usage with your API provider's metadata so you can spot expensive conversations early.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →