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

# Integrations

> Connect Shopify, Stripe, or Cal.com and get conversions without writing code.

If your conversions already live in Shopify, Stripe, or Cal.com, you don't need to build a
[Conversions API](/advertisers/server-conversions) integration. Connect the platform once and
Gravity ingests the events for you — attribution, deduplication, and reporting work exactly the
same way.

<Info>
  Integrations replace the *conversion* half of the setup, not the pixel. You still need the
  [Gravity pixel](/advertisers/pixel) on your site so we can attribute the visit that led to the
  purchase — except for Shopify, which installs its own pixel for you.
</Info>

## Shopify

One-click. Gravity installs a Shopify web pixel on your storefront and subscribes to your
`orders/paid` webhook, so both checkout-time and server-side purchase events flow in.

<Steps>
  <Step title="Open the dashboard">
    Go to **Settings → Organization → Integrations** in the [Gravity dashboard](https://app.trygravity.ai)
    and hit **Connect** on the Shopify row.
  </Step>

  <Step title="Approve the app in Shopify">
    You're sent to Shopify's OAuth grant screen for your `*.myshopify.com` store. Approve it and
    you land back in Gravity.
  </Step>

  <Step title="Done">
    Gravity activates the web pixel and starts syncing your catalog automatically. The row turns
    **verified** once we've seen a valid event from the store.
  </Step>
</Steps>

Purchases arrive as `purchase` conversions with order value and currency. The checkout pixel and
the `orders/paid` webhook are deduplicated against each other on the Shopify order ID, so a single
order is never counted twice.

<Note>
  Because Shopify installs its own pixel, you don't need the manual `gr-pix.js` snippet on your
  storefront. Add it to any *non*-Shopify pages (marketing site, docs, blog) that visitors land on
  first.
</Note>

## Stripe

Two ways to connect, depending on whether you want a one-click flow or full control.

<Tabs>
  <Tab title="Stripe Connect (one-click)">
    **Settings → Organization → Integrations → Connect** on the Stripe row. You authorize Gravity
    through Stripe's OAuth flow and we handle the webhook plumbing on our side.
  </Tab>

  <Tab title="Manual webhook">
    Create a webhook endpoint in your own Stripe dashboard pointing at:

    ```
    https://api.trygravity.ai/stripe-conversions/webhook?api_key=YOUR_API_KEY
    ```

    Subscribe it to `checkout.session.completed` and `invoice.paid`, then paste the endpoint's
    **signing secret** into Gravity under **Settings → Organization → Integrations**. We verify the
    `Stripe-Signature` header on every event with that secret.
  </Tab>
</Tabs>

| Stripe event                 | Recorded as                                  |
| ---------------------------- | -------------------------------------------- |
| `checkout.session.completed` | `purchase` — one-time payments               |
| `invoice.paid`               | `purchase` — first invoice of a subscription |

<Warning>
  Subscription **renewals** are deliberately not counted as new conversions — only the first
  `invoice.paid` for a subscription is. `payment_intent.succeeded` is also ignored: it fires
  underneath the events above and would double-count.
</Warning>

## Cal.com

For demo bookings and consulting flows. Cal.com posts booking events straight to Gravity.

<Steps>
  <Step title="Add a webhook in Cal.com">
    **Settings → Developer → Webhooks → New**, with this subscriber URL:

    ```
    https://api.trygravity.ai/caldotcom/booking?api_key=YOUR_API_KEY
    ```

    Your advertiser API key lives in the Gravity dashboard under **Settings → Organization**.
  </Step>

  <Step title="Use the same key as the signing secret">
    Paste that **same API key** into Cal.com's **Secret** field. Gravity verifies the
    `x-cal-signature-256` HMAC against it — bookings that fail verification are still recorded, but
    flagged as unverified.
  </Step>

  <Step title="Pick your triggers">
    Subscribe to the booking events you care about. Each maps to its own conversion event type:

    | Cal.com trigger       | Conversion event      |
    | --------------------- | --------------------- |
    | `BOOKING_CREATED`     | `booking_created`     |
    | `BOOKING_CONFIRMED`   | `booking_confirmed`   |
    | `BOOKING_RESCHEDULED` | `booking_rescheduled` |
    | `BOOKING_CANCELLED`   | `booking_cancelled`   |
    | `MEETING_ENDED`       | `meeting_ended`       |
  </Step>
</Steps>

Attendee email and phone are hashed (SHA-256) on ingest — Gravity stores the hash, not the raw
value.

<Tip>
  Attribution comes from the Gravity click IDs the pixel writes into your booking page URL. Pass
  them through to Cal.com as booking `metadata.attribution` (`grclid`, `grcpid`, `grpuid`,
  `gradid`) so bookings tie back to the ad that drove them. If only `grclid` makes it through, we
  resolve the rest server-side.
</Tip>

## Check what's connected

The [Dashboard API](/advertisers/dashboard-api) exposes your live connections:

```bash theme={null}
curl "https://platform.trygravity.ai/advertiser-dashboard/integrations" \
  -H "X-API-Key: YOUR_API_KEY"
```

## Next

<CardGroup cols={2}>
  <Card title="Conversions API" icon="code" href="/advertisers/server-conversions">
    Not on one of these platforms? Send conversions from your own backend.
  </Card>

  <Card title="Advertiser pixel" icon="eye" href="/advertisers/pixel">
    Required for attribution on everything except Shopify storefronts.
  </Card>
</CardGroup>
