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.

Why server-side?

The Gravity pixel tracks page views and auto-detects some conversions client-side. But for the highest fidelity — especially for purchases, signups, and other backend-confirmed events — sending conversions server-to-server is more reliable:
  • More reliable — server-side calls aren’t affected by browser extensions or network conditions
  • Richer data — attach customer email, order details, and line items your frontend doesn’t have
  • Deduplication — use event_id to prevent double-counting across pixel and server events
  • Offline conversions — attribute phone calls, in-store purchases, and CRM events back to ads

How it works

  1. The Gravity pixel runs on your site and captures attribution context automatically
  2. On conversion, your frontend reads window.gravityPixel.getCAPIData() and sends it to your backend alongside the order
  3. Your backend calls POST /gateway/events with the pixel context plus server-side details (email, order total, line items)

Step 1 — Install the pixel

If you haven’t already, add the pixel to every page:
<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_ADVERTISER_ID');
</script>

Step 2 — Read pixel data on conversion

When the user completes a conversion (purchase, signup, etc.), call getCAPIData() and pass the result to your backend:
// On your checkout confirmation / thank-you page
var capiData = window.gravityPixel.getCAPIData();

fetch('/api/complete-order', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    order_id: 'order-123',
    total: 99.99,
    currency: 'USD',
    email: 'customer@example.com',
    gravity: capiData
  })
});
getCAPIData() returns a ready-to-merge object:
{
  "user_data": {
    "grclid": "abc-click-id",
    "grcpid": "campaign-uuid",
    "grpuid": "publisher-uuid",
    "gradid": "ad-uuid",
    "grsig": "signature",
    "graid": "attribution-id",
    "visitor_id": "gr-visitor-id",
    "session_id": "gr-session-id",
    "client_user_agent": "Mozilla/5.0 ..."
  },
  "event_source_url": "https://yoursite.com/checkout",
  "client_context": {
    "timezone": "America/New_York",
    "screen": { "width": 1920, "height": 1080, "color_depth": 24 },
    "viewport": { "width": 1440, "height": 900 },
    "platform": "macOS",
    "connection": { "type": "4g", "downlink": 10 }
  }
}
getCAPIData() is safe to call at any time after the pixel loads. If the user arrived via a Gravity ad click, the attribution fields will be populated. If not, they return null — the conversion still records, it just won’t be attributed to a specific ad.The client_context object includes device and environment signals (timezone, screen dimensions, platform) captured by the pixel. Pass the entire object through to your backend and include it in the CAPI request — Gravity uses these signals to improve attribution accuracy.

Step 3 — Send the conversion from your backend

Merge the pixel data with your order details and POST to the Gravity gateway. Pick your language:
import requests
import hashlib
import time

API_KEY = "YOUR_GRAVITY_API_KEY"  # From Settings → Organization

def hash_pii(value: str) -> str:
    """SHA-256 hash for PII. Or send plaintext — the API hashes it for you."""
    return hashlib.sha256(value.strip().lower().encode()).hexdigest()

def send_gravity_conversion(order, gravity_data):
    user_data = gravity_data.get("user_data", {})

    response = requests.post(
        "https://api.trygravity.ai/gateway/events",
        params={"api_key": API_KEY},
        json={
            "data": [{
                "event_name": "Purchase",
                "event_time": int(time.time()),
                "event_id": f"order-{order['id']}",
                "action_source": "website",
                "event_source_url": gravity_data.get("event_source_url", ""),
                "user_data": {
                    **user_data,
                    "em": [order["email"]],
                    "external_id": [str(order["customer_id"])],
                },
                "client_context": gravity_data.get("client_context"),
                "custom_data": {
                    "value": order["total"],
                    "currency": order.get("currency", "USD"),
                    "order_id": str(order["id"]),
                    "contents": [
                        {"id": item["sku"], "quantity": item["qty"], "item_price": item["price"]}
                        for item in order.get("items", [])
                    ],
                },
            }],
        },
    )
    return response.json()
Include "test_event_code": "TEST123" to validate your payload without recording a real conversion. Remove it when you go live.

Event types

Event nameWhen to fire
PurchaseOrder completed
LeadForm submission, demo request
CompleteRegistrationAccount created
SubscribeSubscription started
StartTrialFree trial started
InitiateCheckoutCheckout started
AddToCartItem added to cart
ContactContact form or phone call
ScheduleAppointment booked
Custom event names are also accepted (e.g., "event_name": "DownloadWhitepaper").

User data fields

Attribution (from pixel)

These are automatically included when you use getCAPIData():
FieldDescription
grclidGravity click ID
grcpidCampaign ID
grpuidPublisher ID
gradidAd ID
graidAttribution ID
visitor_idGravity visitor ID
session_idCurrent session ID
client_user_agentBrowser user agent string

Device context (from pixel)

The client_context object is automatically included by getCAPIData(). It contains device and environment signals that improve conversion quality:
FieldDescription
timezoneUser’s timezone (e.g. America/New_York)
screenScreen dimensions and color depth
viewportBrowser viewport dimensions
platformOS platform (e.g. macOS, Windows)
connectionNetwork connection type
Pass the entire client_context object through from your frontend to your backend, then include it in the CAPI request — no manipulation is needed on your end. Gravity uses these signals to improve attribution accuracy.

Customer identity (from your backend)

Add these server-side for richer matching:
FieldTypeDescription
emstring[]Email address(es) — plaintext OK, auto-hashed before storage
phstring[]Phone number(s) in E.164 format
fnstringFirst name
lnstringLast name
external_idstring[]Your system’s customer/user IDs
PII fields (em, ph, fn, ln) can be sent as plaintext — the API normalizes and SHA-256 hashes them before storage. No plaintext PII is ever persisted. If you prefer to pre-hash, send 64-character hex strings and the API will detect and accept them as-is.

Custom data

FieldTypeDescription
valuefloatConversion value (e.g., order total)
currencystringISO 4217 currency code (default: USD)
order_idstringYour order/transaction ID
contentsobject[]Line items: { id, quantity, item_price, title }
content_namestringProduct or content name
content_categorystringProduct category
predicted_ltvfloatPredicted customer lifetime value

Response

{
  "events_received": 1,
  "events_processed": 1,
  "events_errored": 0,
  "results": [
    { "event_id": "order-123", "status": "ok", "attributed": true }
  ],
  "test_mode": false
}
StatusMeaning
okEvent processed and stored
duplicateAlready seen (same event_id + event_name within 48 hours)
test_okValidated but not stored (test mode)
skippedUser opted out
errorProcessing failed — see error field

Deduplication

Events are deduplicated by event_id + event_name within a 48-hour window. Always include a unique event_id (e.g., your order ID) to prevent double-counting — especially if you fire both a pixel conversion and a server-side conversion for the same purchase.

Authentication

Pass your API key as a query parameter or Authorization header:
?api_key=YOUR_API_KEY
or
Authorization: Bearer YOUR_API_KEY
Your API key is in Settings → Organization in the Gravity dashboard.

Batch events

Send up to 1,000 events per request by adding more objects to the data array. Each event is processed independently — partial failures don’t reject the batch.

Next

Pixel setup

Install the Gravity pixel on your site.

Analytics

View conversion reports and ROAS.