Skip to main content

Overview

The Shopify Webhook source receives events from your Shopify store at a dedicated HTTPS endpoint and routes each event to a Kafka topic based on its resource type (orders, products, customers, draft orders, fulfillments, inventory items, collections, etc.). You point Shopify at the Streamkap-generated webhook URL, register the topics you care about, and Streamkap takes care of parsing, key extraction, schema inference, and routing. For initial loads or ad-hoc backfills, the source can also snapshot data directly from the Shopify GraphQL Admin API.
This connector is in Beta. Behaviors and defaults may change before general availability.

Prerequisites

  • A Shopify store with Admin access (required to install apps and register webhooks).
  • A Shopify Partners account so you can create a Dev Dashboard app for OAuth credentials (recommended) — or an existing legacy custom app with a permanent access token.
  • A Streamkap workspace with permission to create source connectors.
  • A clear list of the Shopify resources you want to capture (orders, products, customers, etc.).

How It Works

  1. Endpoint provisioning — When you create the source, Streamkap generates a unique HTTPS webhook URL and an API key.
  2. Shopify subscriptions — In Shopify, you register webhook subscriptions for the topics you want (orders/create, products/update, …) pointing at the Streamkap URL with the API key passed as a query parameter.
  3. Header-based routing — Each incoming request carries an X-Shopify-Topic header (orders/create, customers/delete, etc.). The Shopify payload router maps the resource segment to a topic — orders/* events go to orders, products/* events go to products, and so on.
  4. Key extraction — The router pulls the resource id from the JSON body and uses it as the Kafka message key, enabling upsert-style consumption downstream.
  5. HMAC verification (optional) — When you provide the Shopify app’s client secret, each payload is verified against the X-Shopify-Hmac-Sha256 header. Invalid payloads are rejected and (if configured) routed to the DLQ.
  6. Optional fan-out — Array fields (line items, variants, addresses) can be fanned out into their own topics.
  7. Optional snapshot — For initial loads or ad-hoc backfills, the source queries the Shopify GraphQL Admin API with cursor pagination and emits records alongside the live webhook stream.

Streamkap Setup

1. Create the Source

  1. Navigate to Sources and choose Shopify.
  2. Give the source a memorable Name (for example, shopify-prod).

2. Connection Settings (Auth tab)

3. Schema (Shopify Resources)

In the Schema tab, choose the resources you want to capture. The default is orders,products,customers. A resource is the first segment of the X-Shopify-Topic header — for example orders/create and orders/cancelled both map to the orders resource. Each resource becomes a Kafka topic of the same name. The dropdown is pre-loaded with the resources surfaced in the Shopify Admin UI’s webhook picker (Settings → Notifications → Webhooks → Create webhook): Any fan-out topics you configure (see Fan-out) are added automatically.
Advanced — GraphQL Admin API registration. If you register webhooks via the GraphQL Admin API instead of the Admin UI, additional WebhookSubscriptionTopic values are available (for example SUBSCRIPTION_CONTRACTS_*, COMPANIES_*, METAOBJECTS_*, BULK_OPERATIONS_FINISH). The Schema field accepts any resource name — just type the first-segment of the topic header and Streamkap will route it.
Snapshot support is narrower than webhook routing. Only orders, products, customers, draft_orders, collections, and inventory_items can be snapshotted via the GraphQL Admin API — see Snapshot. All other resources stream via webhooks only.

4. Settings

5. Save and Copy the Endpoint

Save the source. Copy the Webhook URL and API Key — you will need them in the next section to configure Shopify.

Shopify Setup

Shopify does not allow custom headers on webhook deliveries — it only sends its own X-Shopify-* headers. Since Streamkap authenticates requests with an api_key, you must pass the key in the webhook URL as a query parameter:
Shopify will POST to this exact URL including the query string, and the connector authenticates the request via the api_key parameter.

1. Create an App in the Partners Dashboard

Note: As of January 2026, Shopify has deprecated legacy custom apps. New apps must be created via the Partners Dashboard. Existing legacy custom apps with permanent tokens still work but cannot be created on new stores.
  1. Go to the Shopify Partners Dashboard (create a partner account if needed).
  2. Click Apps → Create app → Create app manually.
  3. Name it (for example, Streamkap), set the App URL to your Streamkap webhook URL.
  4. Click Create app.

2. Configure API Scopes

Inside the app, go to Configuration → Access scopes and enable the scopes for the topics you plan to receive: Save. For a full CDC-style setup, enable read_orders, read_products, read_customers, and read_inventory at minimum.

3. Install the App and Get Credentials

  1. In the app, open Settings and note the Client ID and Client Secret.
  2. Install the app on your store (from the Partners Dashboard or via Settings → Apps and sales channels → Develop apps in your store admin) and approve the scopes.
You have two options for obtaining the access token Streamkap uses for snapshots. Paste the Client ID and Client Secret into the Streamkap source’s Auth tab. Streamkap handles token acquisition and refresh automatically (Shopify tokens are valid for 24 hours). For webhook registration in the next step you still need a token. Mint one with curl:
The response contains an access_token valid for 24 hours.

Option B — Static access token (legacy custom apps only)

If you have an existing legacy custom app with a permanent token, paste it into the Streamkap source’s Auth tab as Access Token (Legacy). Leave Client ID / Client Secret empty.

4. Register Webhooks via the GraphQL Admin API

The Shopify Admin UI only registers one webhook at a time. For multiple topics, use the GraphQL Admin API. Endpoint: https://YOUR-STORE.myshopify.com/admin/api/2024-10/graphql.json Required header: X-Shopify-Access-Token: YOUR_ACCESS_TOKEN

Register a single webhook

Register all common webhooks at once

Save the following as setup-shopify-webhooks.sh, set the variables, and run it:

Verify registered webhooks

Delete a webhook

Via Shopify Admin UI (Quick Setup)

For a quick setup with a handful of topics:
  1. In Shopify Admin, go to Settings → Notifications → Webhooks.
  2. Click Create webhook.
  3. Select the event (for example Order creation).
  4. Set format to JSON.
  5. Enter your Streamkap webhook URL with the API key appended: https://YOUR-WEBHOOK-URL?api_key=YOUR_API_KEY.
  6. Save and repeat for each event.

Event Routing Reference

The payload router parses the X-Shopify-Topic header on each incoming request and routes by resource segment. Topics ending in /delete set __deleted: true on the output record so downstream sinks can issue tombstones. __op is emitted as a Kafka header (c create, u update, d delete, r snapshot). Each record additionally carries __changeType (CREATE, UPDATE, DELETE, CANCELLED, FULFILLED, PAID, SNAPSHOT, …) in the value.

Fan-out

Shopify resources contain arrays of objects (line items, variants, addresses, tax lines, …) that most warehouse destinations can’t store cleanly as a single column. Fan-out emits one record per array element to a dedicated topic so each child becomes its own row. Set Fan-out Fields to a comma-separated list of resource.field pairs from the allowed set:
Fan-out topics are added to the Schema list automatically — you do not need to register them manually. Streamkap rejects unknown fan-out entries when you save the source. Each fan-out record contains the array element’s fields plus:
  • _ctx_event_id — the originating X-Shopify-Event-Id for correlation.
  • _ctx_shop_domain — the originating X-Shopify-Shop-Domain.
Fan-out topics do not emit tombstone records when array items are removed (for example when a line item is removed from an order). To handle deletions, configure the downstream sink for delete-and-reinsert on each parent event, or treat each parent record as the source of truth and full-replace the child rows.

HMAC Verification

To cryptographically verify that webhooks come from Shopify, set HMAC Secret in the Auth tab to your Shopify app’s client secret. Every payload is then verified against the X-Shopify-Hmac-Sha256 header using HMAC-SHA256. Failed payloads are rejected (and sent to the DLQ when enabled). Leave the field empty to skip verification — useful while testing.

Snapshot

Once your source is live, you can run a snapshot from the Streamkap UI to load historical data for selected resources. Webhook streaming continues to run in parallel — snapshot is a one-time backfill, not an alternative to live events.

Snapshottable Resources

Only these resources can be snapshotted via Shopify’s GraphQL Admin API: All other resources you select in the Schema tab (fulfillments, shop, discounts, carts, etc.) cannot be snapshotted — they only receive live events via webhooks once you register them in Shopify. This is a limitation of the Shopify Admin API, which exposes historical-fetch endpoints only for the resources above.

Troubleshooting

Limitations

  • The Shopify Webhook source is currently Beta.
  • Shopify expects a 200 response within 5 seconds. The connector responds immediately and processes asynchronously; failures are captured in the DLQ when enabled.
  • Snapshot supports only the resources backed by the GraphQL Admin API listed above. Other resources (e.g., fulfillments, shop) are streamed via webhooks only.
  • Mandatory Shopify compliance webhooks (customers/data_request, customers/redact, shop/redact) are accepted by the endpoint but currently routed to the unknown topic; you should respond to them out of band per Shopify’s requirements.
  • Maximum payload size is 50 MB and maximum header size is 64 KB.
  • The connector runs as a single task; horizontal scaling requires multiple source instances.

See Also