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 devicedevice.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.

Lead forms

When a campaign is configured as a lead_form ad unit, the AdResponse includes a lead_form field:
When present, render the form and POST the submitted values to lead_form.submit_url.

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.