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

# Integrations

> Connect SnowSEO with your favorite CMS platforms, analytics tools, and SEO services to create a unified content workflow.

Integrations let you connect SnowSEO to the external tools your team already uses — so you can publish content, track performance, and monitor search visibility without switching between platforms.

<Info>
  All integrations are configured **per brand**. If you manage multiple websites, connect each brand to its own set of tools independently.
</Info>

***

## Accessing the Integrations Page

To manage your integrations, open the **user menu** at the bottom-left of the dashboard and select **Integrations** from the dropdown.

<img src="https://mintcdn.com/kapybarallc/jdyimTFP-RkUJ3w1/images/others/integrations-step1.png?fit=max&auto=format&n=jdyimTFP-RkUJ3w1&q=85&s=e758e7e9f493fbe83af54d69aa56a9ee" alt="Accessing the Integrations page from the dashboard user menu — the Integrations option is highlighted in the dropdown" className="rounded-xl border shadow-lg mt-6" width="1130" height="915" data-path="images/others/integrations-step1.png" />

This opens the Integrations drawer with tabs organized by function: **CMS & Publishing**, **Analytics & Performance**, **SEO & AI Tools**, **Social Media**, **API**, and **MCP**.

Each integration uses an accordion pattern — click the row to expand it and see connection details.

***

## Recommendations: What to Connect First

Not all integrations are equally important. Here's the priority order:

| Priority | Integration                       | Why                                                                                                                                                    |
| -------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **1st**  | Google Search Console             | Without it, SnowSEO cannot show your real search traffic, keyword positions, or click-through rates. This is the foundation of almost every dashboard. |
| **2nd**  | Your CMS (WordPress, Ghost, etc.) | Unlocks **Publish** and **Schedule** buttons in the Article Editor so you can push content live without copy-pasting.                                  |
| **3rd**  | Google Analytics                  | Enables **Content ROI** and **Website Traffic** metrics on published articles.                                                                         |
| **4th**  | Bing Webmaster Tools              | Captures the \~6–10% of search traffic that comes from Bing, especially if your audience skews enterprise or older demographics.                       |
| **5th**  | PostHog                           | If you run a SaaS product, this connects product analytics with your SEO performance data.                                                             |

***

<Tabs>
  <Tab title="CMS & Publishing">
    The **CMS & Publishing** tab lists content management platforms you can connect for direct article publishing. Once linked, you can push SEO-optimized articles from SnowSEO straight to your live website.

    <img src="https://mintcdn.com/kapybarallc/jdyimTFP-RkUJ3w1/images/others/integrations-step2.png?fit=max&auto=format&n=jdyimTFP-RkUJ3w1&q=85&s=05d6979bfd383844e39cc4632c2b5654" alt="CMS and Publishing tab showing WordPress, Ghost CMS, Webflow, and Shopify integrations with Connect buttons" className="rounded-xl border shadow-lg mt-6" width="1724" height="927" data-path="images/others/integrations-step2.png" />

    <Tip>
      Connecting a CMS unlocks the **Publish Now** and **Schedule** buttons inside the Article Editor. Without it, you can still write and optimize content — but you'll need to manually copy the output to your website.
    </Tip>

    ***

    ### WordPress

    Connect your WordPress site to create and publish posts directly from SnowSEO. Supports both **WordPress.com** and self-hosted **WordPress.org** installations.

    <Warning>
      **WordPress Connection Prerequisites & Common Issues:**

      * **WordPress Version**: You must be running **WordPress 5.6 or higher**. Older versions do not support Application Passwords or the REST API v2 needed for the OAuth and Password methods.
      * **REST API Blocks**: Security plugins (like **Wordfence**, **iThemes Security**, or **Sucuri**) and some hosting configurations can block the WordPress REST API. Make sure `/wp-json/` endpoints are accessible.
      * **Disabling Security Blocks**: If you use Wordfence, ensure it is not blocking Application Passwords (you may need to allow them in Wordfence settings or temporarily disable the plugin to connect).
      * **Fallback to Plugin Method**: If your firewall or security setup strictly blocks the REST API, use the **Plugin** method which is designed to bypass these restrictions.
    </Warning>

    SnowSEO offers **three connection methods** — choose based on your hosting setup:

    <Tabs>
      <Tab title="OAuth">
        **Best for:** WordPress.com sites and self-hosted sites where the WordPress REST API is accessible.

        This is the simplest method — no manual credential management required.

        <img src="https://mintcdn.com/kapybarallc/qpYpmVePv6UCygCS/images/integrations/wordpress-oauth.gif?s=aa2c2e4a64dcb1c9cab2ccc834d4317b" alt="OAuth connection flow showing WordPress authorization window" className="rounded-xl border shadow-lg mt-6" width="1920" height="924" data-path="images/integrations/wordpress-oauth.gif" />

        <Steps>
          <Step title="Click Connect + on the WordPress row">
            In SnowSEO, find WordPress in the CMS & Publishing tab and click **Connect +**. The panel expands with three tab options.
          </Step>

          <Step title="Select the OAuth tab">
            It's selected by default. You'll see a single field: **Site URL**.
          </Step>

          <Step title="Enter your WordPress Site URL">
            Type the main domain of your WordPress site (e.g., `wordpress-blog.com`). Do **not** include `/wp-login`, `/wp-admin`, or `https://` — those are added automatically.
          </Step>

          <Step title="Click Connect">
            Click **+ Connect**. A secure WordPress authorization window opens where you sign in to your WordPress admin and grant SnowSEO permission. Once authorized, the status changes to **Connected**.
          </Step>
        </Steps>

        <Tip>
          OAuth is the fastest method. Try it first — if your WordPress site blocks the REST API (common with certain hosting providers or security plugins), fall back to the Password or Plugin method.
        </Tip>
      </Tab>

      <Tab title="Password">
        **Best for:** Self-hosted WordPress.org sites where OAuth is blocked or unavailable.

        Uses an **Application Password** — a revocable token generated inside WordPress, not your main login password.

        <img src="https://mintcdn.com/kapybarallc/qpYpmVePv6UCygCS/images/integrations/wordpress-password.gif?s=570666d93c70aa039114d86fa0e998af" alt="Password connection flow showing Application Password setup" className="rounded-xl border shadow-lg mt-6" width="1920" height="922" data-path="images/integrations/wordpress-password.gif" />

        <Steps>
          <Step title="Click Connect + and select the Password tab">
            In SnowSEO, expand the WordPress panel and select the **Password** tab.
          </Step>

          <Step title="Enter your WordPress Site URL">
            Type your site's main domain (e.g., `wordpress-blog.com`). No protocol, no `/wp-admin`.
          </Step>

          <Step title="Enter your Admin Username">
            Type the WordPress username you log in with. This user **must have admin privileges**.
          </Step>

          <Step title="Generate an Application Password in WordPress">
            In your WordPress admin:

            1. Go to **Users → Your Profile**
            2. Scroll to the **Application Passwords** section
            3. Type a name (e.g., "SnowSEO") and click **Add New Application Password**
            4. Copy the generated password — it looks like `xxxx xxxx xxxx xxxx xxxx xxxx`
          </Step>

          <Step title="Paste the Application Password and connect">
            Back in SnowSEO, paste the generated password into the **Application Password** field (use the eye toggle to reveal/hide it). Click **+ Connect**.
          </Step>
        </Steps>

        <Warning>
          The Application Password is **not** your WordPress login password. It's a separate, revocable credential for third-party access. You can revoke it anytime from your WordPress profile without affecting your main login. If you revoke it, the SnowSEO integration will break — just generate a new one and reconnect.
        </Warning>
      </Tab>

      <Tab title="Plugin">
        **Best for:** Sites behind firewalls, using non-standard hosting, or where security plugins block REST API access.

        Uses a dedicated SnowSEO WordPress plugin with a site token (API key) for the most reliable connection.

        <img src="https://mintcdn.com/kapybarallc/qpYpmVePv6UCygCS/images/integrations/wordpress-plugin.gif?s=7f3e6c99b7db7b7a0d4b3b89160aa412" alt="Plugin connection flow showing API key setup in WordPress" className="rounded-xl border shadow-lg mt-6" width="1920" height="910" data-path="images/integrations/wordpress-plugin.gif" />

        <Steps>
          <Step title="Click Connect + and select the Plugin tab">
            In SnowSEO, expand the WordPress panel and select the **Plugin** tab.
          </Step>

          <Step title="Download the SnowSEO WordPress plugin">
            Click **Download Plugin** to download the `.zip` file.
          </Step>

          <Step title="Install and activate the plugin in WordPress">
            In your WordPress admin:

            1. Go to **Plugins → Add New → Upload Plugin**
            2. Upload the downloaded `.zip` file
            3. Click **Install Now**, then **Activate**
          </Step>

          <Step title="Generate an API Key in SnowSEO">
            Back in SnowSEO, click **Generate API Key**. A unique key appears (e.g., `sw_live_941cbd0fbbcf...`). Click the copy button.
          </Step>

          <Step title="Enter the site token in the WordPress plugin">
            In WordPress, open **SnowSEO** in the admin sidebar, paste the site token from SnowSEO (Plugin tab → **Generate API Key**), and click **Save & Connect**.
          </Step>

          <Step title="Wait for automatic activation">
            In SnowSEO, the Connect button shows **Waiting for activation** with a spinner. Once the plugin validates the key with SnowSEO's servers, the status automatically changes to **Connected**. This usually takes a few seconds.
          </Step>
        </Steps>

        <Tip>
          If the status stays on "Waiting for activation" for more than a minute, check that your WordPress site can make outbound HTTPS requests to SnowSEO's API. Some hosts block outbound connections — contact your hosting provider if needed.
        </Tip>
      </Tab>
    </Tabs>

    **Once connected**, the WordPress accordion shows:

    * **Site Title** — Your WordPress site name
    * **Site URL** — The connected domain
    * **Connection Method** — Tag showing OAuth, App Password, or Plugin
    * **Disconnect** button (red) — removes the integration

    <Info>
      You can only have **one active CMS integration per brand**. If you connect WordPress, then try to connect Ghost, the previous connection gets replaced. Disconnect first if you want to switch platforms cleanly.
    </Info>

    ***

    ### Ghost CMS

    Professional publishing platform. Connect your Ghost publication to manage and schedule content directly from SnowSEO.

    <img src="https://mintcdn.com/kapybarallc/qpYpmVePv6UCygCS/images/integrations/ghost-connect.gif?s=c9875fee86bccb967e996539c0a82211" alt="Ghost CMS connection flow showing Admin API key setup" className="rounded-xl border shadow-lg mt-6" width="1920" height="922" data-path="images/integrations/ghost-connect.gif" />

    <Steps>
      <Step title="Click Connect + on the Ghost CMS row">
        In SnowSEO, find Ghost CMS and click **Connect +**.
      </Step>

      <Step title="Create a custom integration in Ghost">
        In your Ghost admin:

        1. Go to **Settings → Integrations**
        2. Click **Add custom integration** and name it "SnowSEO"
        3. Ghost generates an **Admin API Key** and shows an **API URL** — keep this screen open
      </Step>

      <Step title="Paste the Admin API Key">
        Copy the **Admin API Key** from the integration and paste it into the **Admin API Key** field.
      </Step>

      <Step title="Enter the API URL and connect">
        Copy the **API URL** shown in the same integration (e.g., `https://your-site.ghost.io`) into the **API URL** field, then click **+ Connect**. Use this exact URL — **not** your public site domain. They are often different, and using the public domain can cause publishing to fail with an authentication error. The status changes to **Connected** once verified.
      </Step>
    </Steps>

    <Tip>
      Use the **API URL** Ghost shows inside the custom integration, not your public-facing site address — on Ghost(Pro) with a custom domain these differ, and the public domain can redirect API requests in a way that drops authentication. The Admin API Key includes both a key ID and a secret in a single string — SnowSEO handles everything else. If you ever regenerate the key in Ghost, you'll need to reconnect SnowSEO with the new key.
    </Tip>

    ***

    ### Webflow

    Connect Webflow to manage CMS items on your published sites.

    <img src="https://mintcdn.com/kapybarallc/qpYpmVePv6UCygCS/images/integrations/webflow.gif?s=3601b55860144f4ceb6c82b4553f7f5f" alt="Webflow connection flow showing Site ID and API token setup" className="rounded-xl border shadow-lg mt-6" width="1920" height="920" data-path="images/integrations/webflow.gif" />

    <Steps>
      <Step title="Click Connect + on the Webflow row">
        In SnowSEO, find Webflow and click **Connect +**.
      </Step>

      <Step title="Get your Webflow Site ID">
        In your Webflow dashboard:

        1. Open the site you want to connect
        2. Go to **Site settings → General**
        3. Find your **Site ID** (a string like `1234567890abcdef`)
           Leave this tab open — you'll need it after creating the token.
      </Step>

      <Step title="Create an API Token in Webflow">
        Still in Webflow:

        1. Go to **Account → Integrations → API access**
        2. Click **Generate API token**
        3. Give it a name (e.g., "SnowSEO")
        4. Enable **CMS Read & Write** access — required for publishing
        5. Copy the token immediately — Webflow only shows it once
      </Step>

      <Step title="Enter the Site ID and paste the token">
        Back in SnowSEO:

        1. Paste the **Site ID** into the first field
        2. Paste the **API Token** into the second field
        3. Click **+ Connect**

        Once connected, you'll see two dropdowns:

        * **Webflow Site** — Select which site to publish to
        * **CMS Collection** — Select which collection (blog, articles, etc.)
      </Step>
    </Steps>

    <Warning>
      The API Token is shown only **once** by Webflow. If you lose it, you must generate a new one in Webflow and reconnect. Keep it in a password manager until the SnowSEO connection is verified.
    </Warning>

    <Tip>
      After connecting, make sure you've selected the correct **CMS Collection** in the expanded panel. SnowSEO will only publish to the collection you select. If you don't see any collections, make sure your site has at least one CMS collection defined in Webflow.
    </Tip>

    ***

    ### Framer

    Connect Framer to publish content directly into your Framer CMS. SnowSEO offers **two connection methods** — choose based on how hands-off you want publishing to be:

    <Tabs>
      <Tab title="Server API">
        **Best for:** most users — publishes directly to your Framer CMS from SnowSEO's servers, so you **don't need to keep Framer open**.

        SnowSEO writes articles straight into a Framer CMS collection using a project-scoped **Server API key**. This is Framer's official [Server API](https://www.framer.com/developers/server-api-introduction) (currently in open beta) and works on any Framer plan — no special tier required.

        <Steps>
          <Step title="Create a Server API key in Framer">
            In your Framer project, open **Site Settings → General → API Keys** and click **Add**. Name it (e.g. "SnowSEO"), click **Create**, and **copy the key** — Framer shows it only once.
          </Step>

          <Step title="Copy your Framer project URL">
            Open the project in the Framer **editor** and copy the address-bar URL — it looks like `https://framer.com/projects/YourSite--AbC123`. This is the **project** URL, **not** your published `.framer.app` site URL.
          </Step>

          <Step title="Connect the project in SnowSEO">
            In SnowSEO, expand the **Framer** panel and select the **Server API** tab. Paste the **Project URL** and **Server API Key**, then click **Connect Project**. SnowSEO fetches your project's editable CMS collections.
          </Step>

          <Step title="Choose a collection">
            Pick **Use existing collection** and select the blog/articles collection you want to publish into, or choose **Create SnowSEO collection** to have SnowSEO create a ready-made "SnowSEO Articles" collection for you (handy if the project has no CMS collection yet).
          </Step>

          <Step title="Map the fields">
            Match your SnowSEO article fields to Framer collection fields — **Title** and **Content** are required; **Image**, **Meta Description**, and **Created At** are optional. Common field names are auto-detected and pre-selected. Keep **Add SnowSEO tracking field** on (it's on by default).
          </Step>

          <Step title="Save Framer Setup">
            Click **Save Framer Setup**. The status changes to **Connected** and you can publish articles straight to Framer.
          </Step>
        </Steps>

        <Info>
          **The "SnowSEO Article ID" tracking field is essential.** SnowSEO adds a hidden text field to your collection and stores each article's Framer item ID in it, so re-publishing an edited article **updates the same Framer item** instead of creating a duplicate. This is what makes "update live post" work — leave it enabled.
        </Info>

        <Tip>
          * **Draft vs. Published** — publishing as **Published** also deploys your Framer site so the item goes live; publishing as **Draft** leaves it as a CMS draft (not publicly visible) until you publish the Framer site.
          * **Added a collection or field in Framer?** Use the **refresh** icon next to the collection dropdown to re-fetch collections and fields without reconnecting.
          * **Change your setup later** — the connected panel has a **Reconfigure** button to switch collection or remap fields anytime.
        </Tip>
      </Tab>

      <Tab title="Plugin Key">
        **Best for:** a fallback when you can't use the Server API. Syncs content **only while the SnowSEO Framer plugin is open** inside Framer.

        <Steps>
          <Step title="Generate a Plugin Key in SnowSEO">
            Expand the **Framer** panel, select the **Plugin Key** tab, and click **Generate Plugin Key**. Copy the key — it's shown once.
          </Step>

          <Step title="Paste it into the SnowSEO Framer plugin">
            Open your Framer project, open the SnowSEO plugin, and paste the key where requested.
          </Step>

          <Step title="Keep Framer open to sync">
            Content syncs while the plugin is open. Unlike the Server API method, publishing does not run in the background.
          </Step>
        </Steps>

        <Warning>
          The Plugin Key is shown **once** after generation. Copy it immediately. If you lose it, click **Revoke Key** in the SnowSEO panel and generate a new one.
        </Warning>
      </Tab>
    </Tabs>

    <Info>
      Prefer the **Server API** method whenever possible — it publishes without you needing to keep Framer open, and it's what powers scheduled and automated publishing to Framer.
    </Info>

    ***

    ### Grigora

    Connect a Grigora project to create, update, schedule, and synchronize articles directly from SnowSEO. You can send an article as a **draft** for review or publish it immediately.

    <Steps>
      <Step title="Create a project API key in Grigora">
        In your Grigora dashboard, open **Settings → Advanced → API**. Enter a descriptive name such as `SnowSEO`, click **Create**, and copy the generated key.
      </Step>

      <Step title="Open the Grigora integration in SnowSEO">
        In SnowSEO, go to **Integrations → CMS & Publishing**, find **Grigora**, and click **Connect**.
      </Step>

      <Step title="Paste the API key">
        Paste the key exactly as Grigora displayed it into the **API Key** field. Do not add `Bearer` or another prefix.
      </Step>

      <Step title="Enter your public Grigora site URL">
        Enter the public base URL where readers access your posts, such as `your-site.com/blog`. SnowSEO automatically uses HTTPS and appends each article's slug to this URL.
      </Step>

      <Step title="Connect and verify">
        Click **Connect**. SnowSEO verifies the key with Grigora before saving it. Once connected, the panel displays the public site URL and the Article Editor enables Grigora publishing and scheduling.
      </Step>
    </Steps>

    <Warning>
      Grigora displays an API key only once. Store it securely when you create it. If you lose or revoke it, disconnect Grigora in SnowSEO, generate a new key, and reconnect.
    </Warning>

    **Publishing and synchronization behavior:**

    * **Save as Draft in CMS** creates or updates a Grigora post with `draft` status.
    * **Publish Now** creates or updates the post with `published` status.
    * SnowSEO sends the article's formatted HTML, slug, categories, tags, SEO title and description, featured image, and summary.
    * Re-publishing an already linked article updates the existing Grigora post instead of creating a duplicate.
    * SnowSEO periodically reconciles the linked post's status, first-published time, and public URL with Grigora.

    <Tip>
      Set **Site URL** to the base path immediately before the article slug. For example, if a post is available at `https://example.com/blog/my-post`, enter `example.com/blog`. Grigora's create/update API returns the post ID and slug but not the public URL, so SnowSEO uses this base URL to build the article link.
    </Tip>

    See Grigora's [API key guide](https://help.grigora.co/developers/creating-and-authorizing-an-api-key) if you need help generating or revoking a key.

    ***

    ### Webhook

    Receive real-time CMS publish payloads at your own endpoint. Unlike other CMS integrations, Webhook allows **multiple connections** — you can set up separate webhooks for different services (e.g., a Next.js blog, a custom headless CMS, and a Zapier automation).

    > See a working [Next.js example on GitHub](https://github.com/Snow-SEO/custom-webhook-blog).

    <Steps>
      <Step title="Click Connect on the Webhook row">
        The panel expands. If you have no webhooks yet, an empty form appears automatically.
      </Step>

      <Step title="Enter an Integration Name">
        A descriptive name so your team can identify this connection (e.g., `Next.js Blog`, `Zapier Automation`). Must be 2–30 characters.
      </Step>

      <Step title="Add your Webhook Endpoint URL">
        The destination URL where SnowSEO sends events (e.g., `https://your-site.com/api/webhook`). Must be **HTTPS** and publicly reachable. In development mode, `http://` URLs are also accepted.
      </Step>

      <Step title="Set an Access Token">
        A secret token you choose. SnowSEO sends this in the `Authorization` header as `Bearer <your-token>`. Your endpoint should verify this token before processing payloads.
      </Step>

      <Step title="Click + Connect">
        SnowSEO sends a `webhook.connected` validation ping to your endpoint, carrying your token in the `Authorization: Bearer` header. Your endpoint should verify that token and reply with a 2xx status — then the webhook is saved and connected. You can add more webhooks by clicking **Add New Webhook**.
      </Step>

      <Step title="Test by publishing an article">
        Publish any article from the dashboard. Your endpoint should receive a `POST` request with the `article.published` or `article.drafted` event payload.
      </Step>
    </Steps>

    **Managing Webhooks:**

    * Each webhook shows a row with its name, endpoint URL, and an **active/inactive toggle**
    * Click the pencil icon to edit name, URL, or secret — SnowSEO re-validates by sending a `webhook.connected` ping after any credential change
    * Click the trash icon to delete the webhook — SnowSEO sends a `webhook.disconnected` event to your endpoint before removal
    * Use **Disable All** to turn off all webhooks at once
    * Toggle **Send events even with another CMS** to have your webhook endpoints notified on every publish and unpublish, even when a CMS like WordPress or Ghost is the publish target. When off (the default), webhooks only fire when a webhook is the publish target. Your endpoints receive the same `article.published` / `article.drafted` / `article.unpublished` payloads; the article's CMS record stays owned by that CMS.
    * The overall integration shows as "Connected" when at least one webhook is active

    **Webhook Payload Structure:**

    When SnowSEO publishes an article, your endpoint receives a `POST` request with the following JSON body:

    ```json theme={null}
    {
      "event": "article.published",
      "timestamp": "2026-05-13T10:30:00.000Z",
      "article": {
        "slug": "my-article-slug",
        "title": "My Article Title",
        "markdown": "Full markdown content without the featured image...",
        "html": "<p>Converted HTML content...</p>",
        "status": "publish",
        "language": "es",
        "categories": ["Guides", "Product"],
        "tags": ["SEO", "How-To"],
        "featuredImage": {
          "url": "https://example.com/image.jpg",
          "caption": "Image caption or null"
        },
        "cms": {
          "provider": "wordpress",
          "articleId": "123",
          "url": "https://your-site.com/blog/my-article"
        },
        "metaData": {
          "metaTitle": "SEO Meta Title",
          "metaDescription": "SEO meta description...",
          "ogTitle": "Open Graph Title",
          "ogDescription": "Open Graph Description",
          "canonicalUrl": "https://example.com/my-article-slug",
          "twitterTitle": "Twitter Card Title",
          "twitterDescription": "Twitter Card Description"
        }
      }
    }
    ```

    `categories` and `tags` are string arrays of the article's taxonomy (empty arrays when none are assigned). If your receiver's CMS supports categories/tags, map them — creating any that don't exist yet.

    `language` is the raw language code the article was written in — always a code, never a display name, so map it yourself. It is a lowercase two-letter code (`en`, `es`, `de`) with three exceptions to handle: Chinese is sent as `zh_CN` or `zh_TW`, and Hebrew is sent as `iw` (the legacy code Google uses, not `he`). Treat the value as an opaque identifier rather than assuming strict ISO 639-1. It reflects the brand's **Writing Language** (Settings ▸ Content & CMS ▸ Articles) at the time the article was created, so it stays stable even if that setting changes later. Articles created before this field existed report the brand's default language.

    The `cms` object is present **only** when the event fired alongside a real CMS publish/unpublish (the "Send events even with another CMS" toggle). It carries that CMS's own post `provider`, `articleId`, and `url` (`url` omitted on unpublish) so your automation can correlate the SnowSEO article with the WordPress/Ghost/etc. post. It is absent when the webhook is the primary publish target.

    **Event Types:**

    * `article.published` — Sent when an article is published
    * `article.drafted` — Sent when an article is saved as draft
    * `article.unpublished` — Sent when an article is unpublished or removed
    * `webhook.connected` — One-time validation ping sent after connecting or updating credentials
    * `webhook.disconnected` — Sent to your endpoint before the webhook is removed

    **Response (optional):**

    Your endpoint can optionally return JSON with `cmsArticleId` and/or `cmsUrl` to store CMS metadata back to SnowSEO:

    ```json theme={null}
    {
      "cmsArticleId": "your-internal-article-id",
      "cmsUrl": "https://your-site.com/articles/my-article-slug"
    }
    ```

    <Tip>
      Always validate the `Authorization` Bearer token in your webhook handler. Log failed requests for easier debugging. The access token is encrypted at rest but sent in plaintext with each request.
    </Tip>

    ***

    ### Shopify

    <Note>
      **Coming soon.** Publish SEO-optimized articles to your Shopify store blog. The integration fields are already built — connect your shop domain and Admin API access token once released.
    </Note>
  </Tab>

  <Tab title="Analytics & Performance">
    The **Analytics & Performance** tab connects your traffic and user-behavior tools. This gives you a single dashboard view of how your content is performing.

    <img src="https://mintcdn.com/kapybarallc/jdyimTFP-RkUJ3w1/images/others/integrations-step3.png?fit=max&auto=format&n=jdyimTFP-RkUJ3w1&q=85&s=665ec4864cf5301c16e81b8710e45d41" alt="Analytics and Performance tab showing PostHog and Google Analytics integrations with Connect buttons" className="rounded-xl border shadow-lg mt-6" width="1715" height="914" data-path="images/others/integrations-step3.png" />

    <Note>
      Connecting **Google Analytics (GA4)** enables the **Content ROI** and **Website Traffic** metrics on published articles. Without it, these sections show as unavailable in the content performance view.
    </Note>

    ***

    ### Google Analytics

    Connect Google Analytics (GA4) to track website traffic, user behavior, and acquisition channels within your SnowSEO dashboard.

    <Steps>
      <Step title="Click Connect + on the Google Analytics row">
        In SnowSEO, find Google Analytics and click **Connect +**.
      </Step>

      <Step title="Sign in with your Google account">
        A secure OAuth window opens. Sign in with the Google account that has access to your GA4 property and grant SnowSEO read-only permissions.
      </Step>

      <Step title="Select your GA4 property">
        If your account has access to multiple GA4 properties, choose the one corresponding to this brand. Use the dropdown in the expanded panel.
      </Step>

      <Step title="Confirm the connection">
        Status changes to **Connected**. SnowSEO begins pulling traffic data — you'll see Website Traffic and Content ROI metrics on your articles.
      </Step>
    </Steps>

    <Tip>
      Google Analytics data can take **24–48 hours** to fully sync after initial connection. If you don't see data immediately, check back the next day before troubleshooting.
    </Tip>

    ***

    ### PostHog

    Connect your PostHog instance to track product analytics and user engagement alongside your SEO data.

    <Steps>
      <Step title="Click Connect + on the PostHog row">
        The panel expands with **four fields** and an inline guide card showing where to find each key.
      </Step>

      <Step title="Get your PostHog Host URL">
        Your PostHog instance URL. If you use PostHog Cloud, this is `https://us.i.posthog.com` (US) or `https://eu.i.posthog.com` (EU). For self-hosted, use your own domain.
      </Step>

      <Step title="Get your Project API Key">
        In PostHog:

        1. Go to **Project Settings → Project API Key**
        2. Copy the key — it starts with `phc_`
      </Step>

      <Step title="Get your Personal API Key">
        In PostHog:

        1. Click your avatar → **User Settings → User API Keys**
        2. Click **Create personal API key** and name it "SnowSEO"
        3. Copy the key — it starts with `phx_`
      </Step>

      <Step title="Get your Project ID">
        In PostHog, your Project ID is a numeric value. You can find it in **Project Settings** or in the URL when you're on a project page (e.g., `app.posthog.com/project/12345` — the `12345` is your Project ID).
      </Step>

      <Step title="Enter all fields and connect">
        Back in SnowSEO, fill in all four fields and click **Connect to PostHog**.
      </Step>
    </Steps>

    <Tip>
      PostHog requires **both** the Project API Key (`phc_`) and the Personal API Key (`phx_`) — they serve different purposes. The Project API Key identifies the project, while the Personal API Key allows SnowSEO to fetch data on your behalf.
    </Tip>

    <Info>
      SnowSEO only reads analytics data from PostHog. Your events, feature flags, and experiments are never modified or deleted.
    </Info>

    ***

    ### Plausible

    Connect your Plausible instance to track privacy-friendly, cookieless analytics alongside your SEO data.

    <Steps>
      <Step title="Click Connect + on the Plausible row">
        The panel expands with three fields and an inline guide showing where to find each value.
      </Step>

      <Step title="Enter your Plausible Host URL">
        Your Plausible instance URL. For Plausible Cloud this is `https://plausible.io`. For self-hosted, use your own domain (include `https://`, no trailing slash).
      </Step>

      <Step title="Create an API Key in Plausible">
        [Access your API Key Settings](https://plausible.io/settings/api-keys), click **New API Key**, select **Stats API** as the type, give it a name (e.g., "SnowSEO"), and copy it — Plausible only shows it once.
      </Step>

      <Step title="Enter your Site ID">
        Your Site ID is the domain you registered in Plausible (e.g., `yourdomain.com`). You can find it on your Plausible Sites overview — it's the domain listed under each site, without `https://`.
      </Step>

      <Step title="Click Connect to Plausible">
        Once all three fields are filled, click **Connect to Plausible**. SnowSEO validates your credentials and shows a success toast on completion.
      </Step>
    </Steps>

    <Tip>
      Plausible is cookieless and privacy-first, so it doesn't use JavaScript cookies or fingerprinting to distinguish new from returning visitors — these metrics are estimated. The data is accurate but calculated differently from GA4 or PostHog.
    </Tip>

    <Info>
      SnowSEO only reads analytics data from Plausible. Your site configuration, goals, and funnels are never modified or deleted.
    </Info>

    ### Looker Studio

    <Note>**Coming soon.** Push SnowSEO metrics into customizable dashboards for stakeholder reporting.</Note>

    ### Umami

    <Note>**Coming soon.** Connect self-hosted, open-source analytics data to SnowSEO.</Note>

    ### Microsoft Clarity

    <Note>**Coming soon.** Bring session recordings, heatmaps, and behavior insights into your content performance workflows.</Note>

    ### Mixpanel

    <Note>**Coming soon.** Combine product-event analytics with SEO and content outcomes.</Note>
  </Tab>

  <Tab title="SEO & AI Tools">
    The **SEO & AI Tools** tab connects SnowSEO to search engines and SEO platforms. These integrations provide the real ranking data and search visibility insights that power most of SnowSEO's analytics.

    <img src="https://mintcdn.com/kapybarallc/jdyimTFP-RkUJ3w1/images/others/integrations-step4.png?fit=max&auto=format&n=jdyimTFP-RkUJ3w1&q=85&s=c93ea8a94b6d2b9a1f72eab0e4b17032" alt="SEO and AI Tools tab showing a connected Google Search Console integration with account details and Bing Webmaster Tools" className="rounded-xl border shadow-lg mt-6" width="1714" height="915" data-path="images/others/integrations-step4.png" />

    <Warning>
      **Google Search Console is the single most important integration.** Without it, SnowSEO cannot display your real website traffic, historical keyword positions, or search performance data. Connect it as your very first step after adding a brand.
    </Warning>

    ***

    ### Google Search Console

    Unlocks real search traffic data, keyword impressions, click-through rates, and indexing status.

    <Steps>
      <Step title="Click Connect + on the Google Search Console row">
        In SnowSEO, find Google Search Console and click **Connect +**.
      </Step>

      <Step title="Sign in with your Google account">
        A secure OAuth window opens. Sign in with the Google account that owns (or has full access to) the Search Console property for your website.
      </Step>

      <Step title="Select your Search Console property">
        Once connected, the expanded panel shows a **Search Console Property** dropdown. If your account manages multiple properties, select the correct one (e.g., `snowseo.com` — both **Domain** and **URL prefix** properties are supported). Each property shows a permission badge indicating your access level (Full, Owner, Restricted, or Unverified).
      </Step>

      <Step title="Data starts syncing">
        Status changes to **Connected**. SnowSEO begins syncing impressions, clicks, average position, and CTR data.
      </Step>
    </Steps>

    **Managing Your Connection:**

    | Action              | What it does                                                                                                 |
    | ------------------- | ------------------------------------------------------------------------------------------------------------ |
    | **Switch Property** | Change which Search Console property data is fetched from. Use the dropdown in the expanded panel.           |
    | **Reconnect**       | Re-authenticates the connection — useful if your access token expired or you need to switch Google accounts. |
    | **Disconnect**      | Removes the integration. Historical data already imported is retained, but SnowSEO stops pulling new data.   |

    <Tip>
      If you see "No properties found" after connecting, it means your Google account doesn't have any verified Search Console properties. Go to [Google Search Console](https://search.google.com/search-console) first, add and verify your property, then reconnect SnowSEO.
    </Tip>

    ***

    ### Bing Webmaster Tools

    Monitor your site's performance on Bing, manage indexing, and receive SEO reports.

    <Steps>
      <Step title="Click Connect + on the Bing Webmaster Tools row">
        In SnowSEO, find Bing Webmaster Tools and click **Connect +**.
      </Step>

      <Step title="Sign in with your Microsoft account">
        A secure OAuth window opens. Sign in with the Microsoft account that has access to your Bing Webmaster Tools property.
      </Step>

      <Step title="Select your site">
        Once connected, use the **Bing Site** dropdown to select the verified site that corresponds to this brand.
      </Step>

      <Step title="Data starts syncing">
        Status changes to **Connected**. SnowSEO begins pulling Bing search performance data.
      </Step>
    </Steps>

    <Tip>
      While Google dominates search for most sites, **Bing accounts for \~6–10% of desktop search** in the US and Europe. If your audience skews enterprise, older demographics, or uses Microsoft Edge/Internet Explorer, Bing data can reveal meaningful traffic you're currently blind to.
    </Tip>

    ***

    ### Google PageSpeed Insights

    Analyze Core Web Vitals and Lighthouse audits across every crawled page in your site. Powers the **Website Audit → Page Speed** tab.

    <Steps>
      <Step title="Click Connect + on the Google PageSpeed Insights row">
        In SnowSEO, find Google PageSpeed Insights and click **Connect +**.
      </Step>

      <Step title="Get your Google API key">
        1. Go to the [PageSpeed Insights Get Started](https://developers.google.com/speed/docs/insights/v5/get-started#APIKey) page
        2. Click **Get a Key** and select or create a GCP project
        3. Copy the generated API key (starts with `AIzaSy`)
      </Step>

      <Step title="Paste the API key and connect">
        Back in SnowSEO, paste the key into the **Google API Key** field and click **Connect**. Status changes to **Active**.
      </Step>
    </Steps>

    <Info>
      Your API key is stored securely. Default Google quota: **25,000 PSI requests/day** per GCP project (plus \~400 per 100s).
    </Info>

    <Tip>
      Once connected, SnowSEO automatically refreshes stale page scores in the background. PSI audits do **not** consume `page_audits` usage — runs are limited to the default Google quota.
    </Tip>

    **Connected state:** Shows an **Active** badge and the date the API key was first connected.

    **Disconnect:** Removes the API key. Page speed data already stored is retained.

    ***

    ### IndexNow

    Instantly notify Bing, Yandex, and other IndexNow-compatible search engines whenever you publish or update a URL — so they re-crawl it immediately instead of waiting for their own schedule.

    <Warning>
      **Requires:** Active plan + owner or admin role on the brand.
    </Warning>

    <Tabs>
      <Tab title="Generate a new key">
        SnowSEO generates a cryptographically random key for you.

        <Steps>
          <Step title="Click Connect + on the IndexNow row">
            The panel expands with options to generate or import a key.
          </Step>

          <Step title="Click Generate Key">
            SnowSEO creates a unique `{key}.txt` file and shows the key.
          </Step>

          <Step title="Download the key file">
            Click **Download Key File** — saves `{key}.txt` to your computer.
          </Step>

          <Step title="Upload the key file to your website root">
            The key file must be accessible at: `https://{your-domain}/{key}.txt`
          </Step>

          <Step title="Verify the key in SnowSEO">
            Back in SnowSEO, click **Verify**. SnowSEO fetches the file to confirm it exists and contains the correct key.
          </Step>

          <Step title="Status updates to Connected & Verified">
            Once verified, the accordion shows: **Verified on \[date]**. You can now submit URLs.
          </Step>
        </Steps>
      </Tab>

      <Tab title="Use an existing key">
        If you already have an IndexNow key deployed on your server:

        <Steps>
          <Step title="Click Connect + → switch to Existing Key tab">
            The panel shows a field to paste your key.
          </Step>

          <Step title="Paste your key">
            Keys must be **8–128 characters**: letters, digits, or dashes only (e.g., `abc123-def456`).
          </Step>

          <Step title="Confirm the expected file location">
            SnowSEO shows the expected URL: `https://{host}/{key}.txt`
          </Step>

          <Step title="Click Verify">
            SnowSEO fetches the file and confirms. Status changes to **Connected & Verified**.
          </Step>
        </Steps>
      </Tab>
    </Tabs>

    <Warning>
      The key file **must stay accessible at all times**. If you delete it or your server blocks the URL, future IndexNow submissions will fail with HTTP 403.
    </Warning>

    ***

    ### Submitting URLs to IndexNow

    Once verified and active, you can submit URLs to Bing, Yandex, and other compatible engines in one request.

    **Limits:**

    * Up to **10,000 URLs per submission**
    * All URLs must belong to the **same verified host**

    **When to submit:**

    * After publishing a new article or blog post
    * After bulk content updates (e.g., refreshing 50 old posts)
    * After changing URL slugs — submit the new URL so engines re-crawl it
    * Before a major product launch or redesign

    <Tip>
      IndexNow sends **one request** that reaches all participating engines simultaneously. You don't need separate integrations for Bing, Yandex, or other engines — one IndexNow key handles them all.
    </Tip>

    **Managing Your Connection:**

    | Action         | What it does                                                                                     |
    | -------------- | ------------------------------------------------------------------------------------------------ |
    | **Verify**     | Re-checks `{key}.txt` — use if you re-uploaded the file or want to confirm it's still accessible |
    | **Disconnect** | Removes key + host from SnowSEO. Data about past submissions is cleared.                         |

    ***

    ### Ahrefs

    <Note>**Coming soon.** Backlink intelligence, keyword gap opportunities, and competitor SEO signals.</Note>

    ### Semrush

    <Note>**Coming soon.** Keyword research, domain visibility trends, and competitor benchmarking.</Note>

    ### ChatGPT

    <Note>**Coming soon.** AI-assisted SEO workflows directly inside SnowSEO.</Note>
  </Tab>

  <Tab title="Social Media">
    <Note>**Coming soon.** Connect your social media profiles to track brand mentions and engagement alongside your SEO performance. X (Twitter) and LinkedIn integrations are in development.</Note>
  </Tab>

  <Tab title="API (Beta)">
    Generate and manage SnowSEO API keys for programmatic access. **Requires the Scale plan and owner/admin role.** Each API key is scoped to a single brand — the key automatically carries the brand context, so you don't need to pass `teamId` on API requests.

    <Steps>
      <Step title="Click Create new key">
        An inline form appears for naming your key.
      </Step>

      <Step title="Enter a key name">
        Give it a descriptive name (e.g., "Production CI/CD", "Analytics Export").
      </Step>

      <Step title="Click Generate">
        A green success banner appears with the full key. **This is the only time the full key is shown** — copy it immediately and store it securely.
      </Step>

      <Step title="Use the key">
        Include it in the `Authorization` header of your API requests as `Bearer <your-key>`.
      </Step>
    </Steps>

    **Managing Keys:**

    * The keys table shows **Name**, **Key prefix** (last few characters), and **Last used** date
    * Click the delete icon next to any key to revoke it
    * A confirmation modal appears before deletion — this action is irreversible

    <Warning>
      The full API key is shown **only once** at generation. SnowSEO stores only a hash of the key for security. If you lose it, you must revoke the old key and generate a new one.
    </Warning>
  </Tab>

  <Tab title="MCP">
    <Info>
      Connect Claude, Cursor, VS Code, Windsurf, and other AI agents to your SnowSEO data through the **Model Context Protocol**. The MCP server is a proxy over the Developer API — you connect by signing in through your browser (OAuth), so there's no key to copy.
    </Info>

    See the [**MCP Server guide**](/docs/api-reference/mcp) for the endpoint, per-client setup commands, and the full list of available tools.
  </Tab>
</Tabs>

***

## Frequently Asked Questions

<AccordionGroup>
  <Accordion title="Which integrations should I connect first?">
    Start with **Google Search Console** — it unlocks the majority of SnowSEO's value by providing real search data. Next, connect your **CMS** (WordPress, Ghost, Webflow, or Framer) so you can publish directly. Finally, add **Google Analytics** for comprehensive traffic and ROI reporting.
  </Accordion>

  <Accordion title="Can I connect multiple CMS platforms to the same brand?">
    No — each brand can have only **one active CMS integration** at a time. If you need to switch (e.g., migrating from WordPress to Webflow), disconnect the current integration first, then connect the new one. Webhooks are an exception — you can have multiple webhook endpoints active simultaneously.
  </Accordion>

  <Accordion title="What happens to my data if I disconnect an integration?">
    Historical data already imported into SnowSEO (rankings, traffic history, published articles) is **retained**. However, SnowSEO will stop pulling new data from the disconnected service until you reconnect. If you reconnect later, data sync resumes — you don't lose the time in between, but there will be a gap in your historical timeline.
  </Accordion>

  <Accordion title="My integration shows as connected but data isn't appearing — what should I do?">
    First, check the **data sync delay**:

    * **Google Search Console**: Data is updated daily (Google's limitation). Allow up to 48 hours.
    * **Google Analytics**: Can take 24–48 hours for initial data to populate.
    * **PostHog / Plausible / Bing**: Usually available within minutes.

    If it's been longer than expected:

    1. Click **Reconnect** from the expanded integration panel — this re-authenticates the connection
    2. Verify the correct property/site is selected in the dropdown
    3. Check that your account still has the required permissions in the external platform
    4. If using GSC, ensure your property is verified in Google Search Console

    If none of these work, disconnect and reconnect the integration.
  </Accordion>

  <Accordion title="Are my credentials safe?">
    Yes. SnowSEO uses **OAuth 2.0** for all major integrations (Google Search Console, Google Analytics, Bing Webmaster Tools, WordPress). Your passwords are never stored — only secure, revocable access tokens are used.

    For integrations that require API keys or application passwords (PostHog, Ghost, Webflow, WordPress Plugin/Password methods), these are encrypted at rest and sent only when communicating with the respective service. You can revoke access at any time from either SnowSEO or the third-party platform.
  </Accordion>

  <Accordion title="Can I use OAuth, Password, and Plugin methods interchangeably for WordPress?">
    Yes, but each connection replaces the previous one. If you originally connected via OAuth and want to switch to the Plugin method, disconnect first, then reconnect using the new method. Wordpress.com sites must use OAuth — the Password and Plugin methods only work with self-hosted WordPress.org installations.
  </Accordion>

  <Accordion title="I'm using Cloudflare's firewall and WordPress integration keeps failing — what should I do?">
    This happens because Cloudflare's WAF or Bot Fight Mode blocks SnowSEO's requests before they reach your WordPress site. In Cloudflare, go to **Security → WAF → Custom rules** and create a rule that matches path `/wp-json/snowseo/*` where **User-Agent** contains `SnowSEO`, with action **Skip** (skip the relevant checks — WAF Managed Rules, Rate Limiting, and Bot Fight Mode/Super Bot Fight Mode as applicable). Make sure this rule is ordered *before* any rule that would Block or Challenge the request.

    If your firewall setup makes WAF rules impractical to manage, use the **Plugin** connection method instead — it still goes through the same `/wp-json/snowseo/*` routes, so the same Cloudflare rule applies, but the dedicated plugin can better surface which security layer (Cloudflare, Wordfence, etc.) is responsible when a connection attempt fails.
  </Accordion>

  <Accordion title="How do I switch Google Search Console properties without disconnecting?">
    Expand the Google Search Console integration row. There's a **Search Console Property** dropdown that lists all properties your connected Google account has access to. Select a different property from the dropdown — SnowSEO will automatically start fetching data from the new property. No need to disconnect and reconnect.
  </Accordion>

  <Accordion title="My Google OAuth token expired — how do I fix it?">
    Click **Reconnect** in the expanded integration panel. This re-authenticates with Google and issues a fresh token. OAuth tokens typically expire after a few hours, but SnowSEO handles automatic refresh behind the scenes — you should only need to manually reconnect if the refresh fails (e.g., if you changed your Google password or revoked SnowSEO's access).
  </Accordion>

  <Accordion title="PostHog shows 'Connected' but no data appears. What's wrong?">
    Double-check your four fields:

    1. **Host URL** — Make sure it points to your actual PostHog instance (e.g., `https://us.i.posthog.com` not `https://app.posthog.com`)
    2. **Project API Key** (`phc_`) — This is found in Project Settings, not User Settings
    3. **Personal API Key** (`phx_`) — This is found in User Settings → User API Keys
    4. **Project ID** — This is the numeric ID visible in the URL or Project Settings

    The most common mistake is mixing up the two keys or using the wrong Host URL for cloud vs. self-hosted instances.
  </Accordion>

  <Accordion title="Can I integrate SnowSEO with a headless CMS or custom website?">
    Yes — use the **Webhook** integration. Set up an endpoint on your site that receives SnowSEO's publish payloads (title, content, metadata, etc.), then write your own logic to handle the data. This works with any stack: Next.js, Nuxt, Gatsby, custom PHP, or anything else that can accept HTTPS POST requests.
  </Accordion>

  <Accordion title="What permissions does SnowSEO need for Google Search Console?">
    SnowSEO requests **read-only** access to your Search Console account. This means:

    * **Can read**: Impressions, clicks, CTR, keyword positions, indexing status, sitemaps
    * **Cannot modify**: Settings, users, properties, sitemaps, or any other data

    The same applies to Google Analytics — read-only access to GA4 property data only.
  </Accordion>

  <Accordion title="I don't see the API tab — how do I get API access?">
    API keys are available on the **Scale plan** and require an **owner or admin role** in at least one team within the organization. If you're on a lower plan or have a member role, the tab will show a "Scale Plan Required" message. Upgrade your plan or ask your organization owner to generate a key for you.

    Each key is scoped to a specific brand — if you need access to multiple brands, generate a separate key for each one.
  </Accordion>
</AccordionGroup>
