Skip to main content

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.

The Gravity pixel (gr-pix.js) is a required install on your site. It captures attribution context so Gravity can tie ad impressions and clicks back to real outcomes — without it, we can’t measure performance or pay you.
The pixel is required. Without it, Gravity cannot attribute conversions or calculate payouts. Install it before going live.

Web install

Drop this snippet on every page — ideally in your base template / layout:
<!-- Before </body> -->
<script>
  !function(w,d,t,u,n,a,m){w['GravityPixelObject']=n;w[n]=w[n]||function(){
  (w[n].q=w[n].q||[]).push(arguments)},w[n].l=1*new Date();a=d.createElement(t),
  m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m)
  }(window,document,'script','https://code.trygravity.ai/gr-pix.js','gravity');
  gravity('init', 'YOUR_PIXEL_ID');
</script>
Find YOUR_PIXEL_ID in your dashboard under Settings → Platform Settings. It’s a UUID.

Verify it’s firing

  1. Load any page with the pixel installed.
  2. Open your browser DevTools → Network tab and look for a request to api.trygravity.ai/track/gr-events.
  3. A 200 response means the pixel is firing correctly. Events typically appear in your dashboard within ~10 minutes.

In-app browser (WebView)

If your app opens Gravity ad links inside an in-app WebView rather than the system browser, install the pixel inside the WebView too with the inAppBrowser: true flag. This preserves attribution when a user clicks an ad and lands on the advertiser’s page inside your app.
Skip this section if your app opens ad links in the system browser (UIApplication.shared.open(url) or equivalent). The web install above is all you need.

Swift (iOS / iPadOS)

import WebKit

let contentController = WKUserContentController()

// Step 1: config at document start
let configScript = WKUserScript(
    source: """
    window.GRAVITY_PIXEL_CONFIG = {
      inAppBrowser: true,
      pixel_id: "YOUR_PIXEL_ID"
    };
    """,
    injectionTime: .atDocumentStart,
    forMainFrameOnly: true
)
contentController.addUserScript(configScript)

// Step 2: pixel loader + init at document end
let pixelScript = WKUserScript(
    source: """
    !function(w,d,t,u,n,a,m){w['GravityPixelObject']=n;w[n]=w[n]||function(){
    (w[n].q=w[n].q||[]).push(arguments)},w[n].l=1*new Date();a=d.createElement(t),
    m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m)
    }(window,document,'script','https://code.trygravity.ai/gr-pix.js','gravity');
    gravity('init', 'YOUR_PIXEL_ID');
    """,
    injectionTime: .atDocumentEnd,
    forMainFrameOnly: true
)
contentController.addUserScript(pixelScript)

let config = WKWebViewConfiguration()
config.userContentController = contentController
let webView = WKWebView(frame: .zero, configuration: config)

React Native

import { WebView } from 'react-native-webview';

const INJECT_BEFORE = `
  window.GRAVITY_PIXEL_CONFIG = {
    inAppBrowser: true,
    pixel_id: "YOUR_PIXEL_ID"
  };
  true;
`;

const INJECT_AFTER = `
  !function(w,d,t,u,n,a,m){w['GravityPixelObject']=n;w[n]=w[n]||function(){
  (w[n].q=w[n].q||[]).push(arguments)},w[n].l=1*new Date();a=d.createElement(t),
  m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m)
  }(window,document,'script','https://code.trygravity.ai/gr-pix.js','gravity');
  gravity('init', 'YOUR_PIXEL_ID');
  true;
`;

<WebView
  source={{ uri: url }}
  injectedJavaScriptBeforeContentLoaded={INJECT_BEFORE}
  injectedJavaScript={INJECT_AFTER}
/>

Flutter

import 'package:webview_flutter/webview_flutter.dart';

final controller = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..setNavigationDelegate(NavigationDelegate(
    onPageStarted: (_) async {
      await controller.runJavaScript('''
        window.GRAVITY_PIXEL_CONFIG = {
          inAppBrowser: true,
          pixel_id: "YOUR_PIXEL_ID"
        };
      ''');
    },
    onPageFinished: (_) async {
      await controller.runJavaScript('''
        !function(w,d,t,u,n,a,m){w['GravityPixelObject']=n;w[n]=w[n]||function(){
        (w[n].q=w[n].q||[]).push(arguments)},w[n].l=1*new Date();a=d.createElement(t),
        m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m)
        }(window,document,'script','https://code.trygravity.ai/gr-pix.js','gravity');
        gravity('init', 'YOUR_PIXEL_ID');
      ''');
    },
  ));

Troubleshooting

  • Make sure the script loads last in the document (before </body>).
  • Check DevTools Network tab for a request to code.trygravity.ai/gr-pix.js.
  • Check the console for errors. If another script throws before the pixel runs, the pixel load order may need adjusting.
  • Confirm YOUR_PIXEL_ID matches the Pixel ID in Settings → Platform Settings. It’s separate from your API key.
  • Check DevTools Network for api.trygravity.ai/track/gr-events POST requests. A 200 response means we got it; dashboard updates within ~10 minutes.
  • iOS WebKit needs WKWebsiteDataStore.default() (the default). .nonPersistentDataStore() breaks cookie persistence.
  • Verify injectionTime / onPageFinished actually fires — console.log from inside the injected script and capture via WKScriptMessageHandler (Swift) or onMessage (RN).

Next

Going live

Final checklist before flipping production: true.