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.

What you’re going to do

  1. Create an AI platform account and grab your API key.
  2. Install the SDK.
  3. Fire ad requests from your server in parallel with your LLM call.
  4. Render the ad in your chat UI.
  5. Drop the web pixel on your site.
  6. Flip to production when it looks right.
Copy the commands, change a couple of IDs, ship it.
Throughout this guide we use the SDK (@gravity-ai/api + @gravity-ai/react). If you’d rather hit the HTTP API directly, see the API Reference. Same engine, you just own the rendering and tracking.

1. Create your account

  1. Sign up at app.trygravity.ai/publisher/signup.
  2. Create an AI platform account for your app.
  3. From your dashboard, copy the API key and the Pixel ID.
Save the API key as GRAVITY_API_KEY in your server environment.

2. Install the SDK

npm install @gravity-ai/api @gravity-ai/react

3. Prepare context on the client

Call gravityContext() in your chat component so the server gets the session ID and device signals alongside the messages.
import { gravityContext } from '@gravity-ai/api';

const gravity_context = gravityContext({
  sessionId: chatSession.id,      // your conversation ID
  user: { userId: currentUser.id } // your user ID
});

fetch('/api/chat', {
  method: 'POST',
  body: JSON.stringify({ messages, gravity_context }),
});

4. Fetch ads on the server

Fire the ad request in parallel with your LLM call. It never throws — failures return an empty array.
import { Gravity } from '@gravity-ai/api';

const gravity = new Gravity();  // reads GRAVITY_API_KEY from env

app.post('/api/chat', async (req, res) => {
  const { messages } = req.body;

  const adPromise = gravity.getAds(req, messages, [
    { placement: 'below_response', placement_id: 'main' },
  ]);

  // Stream your LLM response in parallel...
  for await (const token of streamYourLLM(messages)) {
    res.write(`data: ${JSON.stringify({ type: 'chunk', content: token })}\n\n`);
  }

  const { ads } = await adPromise;
  res.write(`data: ${JSON.stringify({ type: 'done', ads })}\n\n`);
  res.end();
});

5. Render the ad

import { GravityAd } from '@gravity-ai/react';

function ChatResponse({ response, ads }) {
  return (
    <div>
      <p>{response}</p>
      {ads[0] && <GravityAd ad={ads[0]} variant="card" />}
    </div>
  );
}
GravityAd handles impression tracking automatically via IntersectionObserver, wires the click URL for attribution, and supports 20+ visual variants (card, minimal, inline, spotlight, pill, banner, hyperlink, etc.). Pick whichever fits your UI.

6. Install the pixel (required)

The Gravity pixel is required for attribution and payouts. Without it, Gravity can’t measure visitor journeys or tie ad performance back to real outcomes. Drop this on 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_PIXEL_ID');
</script>
See the Pixel page for verification steps and the in-app browser install if your native app opens ad links in a WebView.

7. Verify, then go live

By default, new Gravity() returns test ads — no billing, safe to iterate. You’ll see the same test creative every time. When you’re ready for real traffic:
const gravity = new Gravity({ production: true });
That’s it. You’re now serving real ads and earning revenue.

Full integration guide

The long version: lifecycle, placements, error handling, framework-specific examples.

Going live checklist

Everything to verify before flipping production: true.

What you didn’t have to think about

  • Retries — the SDK handles transient failures silently.
  • Timeouts — 3 seconds by default. Configurable.
  • Impression / click tracking — fired by GravityAd. Attribution is automatic.
  • Experiments — the engine can test different ad variants for your traffic without you shipping code. See Experiments.
  • Ad quality — Gravity handles the creative; you never hand-pick advertisers.

Troubleshooting

Expected when no campaign matches the conversation — the engine returns 204 No Content and the SDK resolves to { ads: [] }. Gracefully hide the ad slot. Lower the relevancy threshold to fill more aggressively if you want looser matches.
You’re still on test mode. Pass production: true to the constructor or set production=True in Python.
If you’re using GravityAd, it fires on visibility via IntersectionObserver — make sure the ad is actually rendering in the viewport. If you render ads with a custom component, you have to fire the impression pixel yourself: new Image().src = ad.impUrl when the ad becomes visible.