Skip to main content

Installation

Set GRAVITY_API_KEY in your server environment. Only dependency is httpx.

Quick start

Add a few lines to your existing streaming chat endpoint. The ad request runs in parallel with your LLM call — zero added latency.
Works with FastAPI, Starlette, Django, and Flask.

Constructor

The client reuses its HTTP connection pool across calls. Use async with Gravity() as g: or call await gravity.close() for explicit cleanup.

get_ads()

get_ads() reads gravity_context (session, user, and device) from the posted request body and adds the end-user IP from the request headers. It does not invent a device — your browser client must call gravityContext() and post the result, and your backend must leave it in the body it forwards.
Forward the client’s device — device.ip and device.ua are required. If the request reaching Gravity has no end-user ua/ip — e.g. a pure server-to-server call that drops the client context — it is rejected with HTTP 400 and no ad is served. See Device signals.

Return types

Both have .to_dict() methods that serialize to the camelCase JSON shape renderers expect.

Message handling

The SDK sends the last 2 conversational messages to the Gravity API for contextual ad matching. Only messages with recognized roles are included:
  • user, assistant, system, developer, model (Gemini’s alias for assistant)
Messages with other roles (e.g. tool, function, ipython) are filtered out — they typically contain structured data rather than natural language.
gravity.get_ads() never raises. On any failure, it returns AdResult(ads=[]). Safe to fire-and-forget in your stream.

PII hashing

The SDK provides hash_pii() for SHA-256 hashing of emails and phone numbers, matching the normalization used by the Gravity publisher pixel and the advertiser-side conversion pipeline.
Normalization rules:
  • Email: strip().lower()
  • Phone: digits only (e.g. "+1 (555) 123-4567" → "15551234567")
Returns a HashedIdentity dict with only the keys that successfully hashed (email_hash, hashed_phone), so it’s safe to spread into a user dict. email_hash is the canonical email field — it matches the email_hash used by the Index /search API.

Experiments

Experiments are managed server-side. Return the ad normally and render it with the standard SDK component; no experiment-specific branching or tracking code is required.