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.

Installation

npm install @gravity-ai/api
For React components:
npm install @gravity-ai/react
Set GRAVITY_API_KEY in your server environment.

How the pieces fit together

1

Client — prepare context

gravityContext() runs in your chat component. It captures sessionId, userId, and device signals (screen, timezone, locale) and returns a plain object your server can read.
2

Server — fetch ads

gravity.getAds(req, messages, placements) reads the context from the request body, adds the client IP, and POSTs to https://server.trygravity.ai/api/v1/ad. Runs in parallel with your LLM call.
3

Gravity — match and return

The engine matches the conversation against active campaigns, runs an auction, and returns an ad object per requested placement.
4

Client — render

<GravityAd /> renders the ad, fires the impression pixel on visibility, and routes clicks through the tracked URL automatically.

Client — prepare context

In your chat component, prepare user and device signals:
import { gravityContext } from '@gravity-ai/api';

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

// Send it alongside your messages
fetch('/api/chat', {
  method: 'POST',
  body: JSON.stringify({ messages, gravity_context }),
});
gravityContext() auto-detects device signals (screen size, timezone, language) on the client. Required parameters:
ParameterTypeRequiredDescription
sessionIdstringYesUnique session identifier
user.userIdstringYesStable per-user identifier. Thrown at runtime if missing — pass "anonymous" (or any constant) yourself if you genuinely don’t have one. Gets normalized to id on the wire.

Server — fetch ads

import { Gravity } from '@gravity-ai/api';

const gravity = new Gravity({ production: true });

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

  // Fire ad request in parallel with your LLM call
  const adPromise = gravity.getAds(req, messages, [
    { placement: 'below_response', placement_id: 'main' },
  ]);

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

  // Append ads at the end
  const { ads } = await adPromise;
  res.write(`data: ${JSON.stringify({ type: 'done', ads })}\n\n`);
  res.end();
});
The Gravity constructor accepts:
ParameterTypeDefaultDescription
apiKeystringGRAVITY_API_KEY env varYour Gravity API key
gravityApistringProduction URLGravity ad endpoint URL
timeoutMsnumber3000Abort after this many ms
relevancynumber0.2Minimum relevancy threshold, 0.0–1.0. Lower = more ads with weaker contextual matches
productionbooleanfalsefalse returns test ads (no billing)
excludedTopicsstring[]undefinedTopics to exclude from ad matching
gravity.getAds() never throws. On any failure, it returns { ads: [] } silently. Safe to fire-and-forget.

React — render ads

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

function ChatResponse({ response, ads }) {
  return (
    <div>
      <p>{response}</p>
      {ads[0] && <GravityAd ad={ads[0]} variant="card" />}
    </div>
  );
}
The GravityAd component handles impression tracking automatically via IntersectionObserver.
PropTypeDescription
adAdThe ad object from gravity.getAds()
variant"card" | "inline" | "minimal" | "bubble" | "contextual" | "native" | "footnote" | "quote" | "suggestion" | "accent" | "side-panel" | "labeled" | "spotlight" | "embed" | "split-action" | "pill" | "banner" | "divider" | "toolbar" | "tooltip" | "notification" | "hyperlink" | "text-link"Rendering style. When an experiment is active and variant is omitted, the component uses the engine-assigned renderer.

Impression tracking

If you render ads with a custom component instead of GravityAd, fire the impression pixel when the ad becomes visible:
new Image().src = ad.impUrl;
Click tracking is handled automatically through the clickUrl link.

What’s next

Experiments

Run A/B tests on ad creative and rendering. The engine assigns arms; the SDK renders them.

FAQ

No. Fire gravity.getAds() in parallel with your LLM call using Promise.allSettled(). It never throws, so failures are silent.
Set GRAVITY_API_KEY as an environment variable on your server. The Gravity class reads it automatically. You can also pass it via new Gravity({ apiKey: '...' }).
Only if you want pre-built React components. For custom rendering, just use the ad objects from @gravity-ai/api directly.