> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect Shopify

> Create a Shopify custom app, authorize via OAuth, and pick which streams to sync.

<Tip>
  Configure the source at [**AI Training → Data Sources**](https://platform.open.cx/data-sources). This is separate from the [Shopify store connection](/integrations/shopify/connect) used for AI Actions and metadata enrichment — the two can share a custom app if the scopes overlap.
</Tip>

## Before you start

<AccordionGroup>
  <Accordion title="A Shopify custom app with the right scopes" icon="circle-check">
    Knowledge sync authorizes via OAuth using a custom app's **Client ID** and **Client Secret**. Required scopes per stream:

    | Stream   | Required scope            |
    | -------- | ------------------------- |
    | Pages    | `read_online_store_pages` |
    | Articles | `read_content`            |
    | Products | `read_products`           |

    If the custom app you use for the [store connection](/integrations/shopify/connect) already has these scopes, reuse it. Otherwise add them, or create a second custom app just for knowledge sync.
  </Accordion>

  <Accordion title="Owner or admin in OpenCX" icon="key">
    Required to add data sources in [AI Training → Data Sources](https://platform.open.cx/data-sources).
  </Accordion>
</AccordionGroup>

## Set up the sync

<Steps>
  <Step title="Open Data Sources">
    Go to [**AI Training → Data Sources**](https://platform.open.cx/data-sources).
  </Step>

  <Step title="Add a Shopify source">
    Click **Add source → Shopify**. You'll see a **Redirect URL** — copy it and paste it into your Shopify custom app's **Allowed redirection URL** list.
  </Step>

  <Step title="Enter your custom app credentials">
    | Field             | Example                    | Where to get it                                         |
    | ----------------- | -------------------------- | ------------------------------------------------------- |
    | **Shop domain**   | `your-store.myshopify.com` | Your store's `*.myshopify.com` domain.                  |
    | **Client ID**     | —                          | From the Shopify custom app's **API credentials** page. |
    | **Client Secret** | —                          | Same page.                                              |
  </Step>

  <Step title="Select streams">
    Pick which streams to sync. Pages is on by default; Articles and Products are opt-in. You can change the selection later — a re-auth is triggered to update scopes if you add a stream that needs a new one.
  </Step>

  <Step title="Authorize via OAuth">
    Click **Connect with Shopify**. A popup opens asking you to approve the scopes. Approve. When the popup closes, the source row shows **Active**.
  </Step>

  <Step title="Verify in AI Instructions">
    Open [**AI Training → AI Instructions**](https://platform.open.cx/ai-instructions). Synced content appears under **Shopify**, grouped by stream. Pages and products include source URLs back to your storefront; articles don't carry a URL in the sync (Shopify's blog-article URLs require the blog handle, which isn't in the Airbyte data).
  </Step>
</Steps>

## Visibility rules

<AccordionGroup>
  <Accordion title="Pages and articles — by published_at" icon="eye">
    * `published_at` set → **public** (AI can cite in customer replies)
    * `published_at` null → **internal** (agent-facing surfaces only)
  </Accordion>

  <Accordion title="Products — by status" icon="tag">
    * `status === 'active'` → **public**
    * Any other status (draft, archived) → **internal**
  </Accordion>
</AccordionGroup>

## Limits

|                              | Value                                                       |
| ---------------------------- | ----------------------------------------------------------- |
| **Streams synced**           | `pages` (default), `articles` (opt-in), `products` (opt-in) |
| **Sync mode**                | `incremental_append` per stream                             |
| **Sync cadence**             | Airbyte polling — typically every few hours                 |
| **Credential type**          | OAuth 2.0 via custom app (Client ID + Client Secret + shop) |
| **Multi-store**              | One Shopify store per connection                            |
| **Product URLs**             | Present via `handle` + shop domain                          |
| **Article URLs**             | Not available in sync (blog handle missing)                 |
| **Draft / inactive content** | Synced as `internal`                                        |

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Shopify overview" icon="shopify" href="/knowledge/sources/shopify/overview">
    Knowledge vs. AI Actions.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/knowledge/sources/shopify/troubleshooting">
    Scope errors, missing streams, URLs.
  </Card>

  <Card title="Shopify integration" icon="cart-shopping" href="/integrations/shopify/overview">
    Admin API, order lookup, metadata.
  </Card>

  <Card title="AI Actions" icon="bolt" href="/integrations/shopify/ai-actions">
    Real-time tools against your store.
  </Card>
</CardGroup>
