Gravity Ad Engine REST API

Contextual advertising for conversational AI.

Quick Start

Get your first ad in seconds:

curl -X POST https://server.trygravity.ai/api/v1/ad/contextual \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "Where can I buy marathon gear?"}
    ],
    "sessionId": "session-abc-123",
    "userId": "user-xyz-789",
    "numAds": 1,
    "render_context": {
      "placements": [{"placement": "below_response"}]
    },
    "testAd": true
  }'

Get your API key from the Gravity Dashboard.

testAd returns a real ad without an impression id. relevancy controls the minimum relevancy threshold to show an ad (0.0-1.0)

Authentication

All requests require a Publisher API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Message Context

Include the user's current query and the previous assistant response (if available) for better ad matching.

First Turn

Just the user query:

{
  "messages": [
    { "role": "user", "content": "Where can I buy marathon gear?" }
  ]
}

Follow-up Turns

Previous response + current query:

{
  "messages": [
    { "role": "assistant", "content": "What's your budget?" },
    { "role": "user", "content": "Around $150 for good running shoes" }
  ]
}

Integration Types

Select your platform for the recommended request format. More context = better ad relevance = higher CPMs.

POST https://server.trygravity.ai/api/v1/ad/contextual

For: Browser-based AI apps, chatbots, web dashboards

Request Fields

Field Type Description
messages required array Conversation context. Array of {role, content} objects.
sessionId required string Session identifier for frequency capping.
render_context required Render Context Object Describes how the ad will be rendered in your app.
placements required array Array of placement objects (1-3). Length must match numAds.
.placement required string "above_response", "below_response", "inline_response", "left_response", "right_response"
.placement_id string Optional tracking ID for this ad slot.
max_ad_length number Max characters for ad text.
userId string Unique user identifier.
testAd boolean Returns a real ad without an impression id. Use for testing.
numAds number Number of ads to return (1-3). Must match placements length.
Field Type Description
device Device Object Device and location information.
ip required string IP address for geo-targeting. Enables location-based ads.
ua string User agent string. Enables browser/device detection.
browser string "chrome", "safari", "firefox". Enables browser targeting.
device_type string "desktop", "mobile", "tablet".
timezone string IANA timezone. Enables time-based targeting.
locale string Browser locale. Enables localized ads.
user User Object User profile information.
email string User's email for identity matching. Higher CPMs.
subscription_tier string "free", "pro", "enterprise". Premium users = higher value.
web.referrer string Referring URL. Enables traffic source targeting.

Example Request

{
  "messages": [
    { "role": "user", "content": "What are the best practices for React performance?" }
  ],
  "sessionId": "session-web-001",
  "userId": "user-web-789",
  "numAds": 1,
  "testAd": true,
  "render_context": {
    "placements": [
      { "placement": "right_response", "placement_id": "sidebar-1" }
    ],
    "max_ad_length": 200
  },
  "user": {
    "email": "[email protected]",
    "subscription_tier": "pro"
  },
  "device": {
    "ip": "203.0.113.50",
    "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0",
    "browser": "chrome",
    "device_type": "desktop",
    "timezone": "Europe/London",
    "locale": "en-GB"
  },
  "web": {
    "referrer": "https://google.com"
  }
}

Example Response

{
  "ads": [
    {
      "adText": "Speed up your React apps with Vercel — deploy in seconds, scale automatically.",
      "adId": "ad_web123",
      "title": "Vercel - Frontend Cloud",
      "brandName": "Vercel",
      "url": "https://vercel.com",
      "favicon": "https://vercel.com/favicon.ico",
      "impUrl": "https://server.trygravity.ai/imp?grclid=...",
      "clickUrl": "https://server.trygravity.ai/click?grclid=...",
      "payout": 0.02
    }
  ],
  "numAds": 1,
  "totalPayout": 0.02
}

For: Dev tools like Cursor, Claude Code, GitHub Copilot, Windsurf and VS Code extensions

Request Fields

Field Type Description
messages required array Conversation context. Array of {role, content} objects.
sessionId required string Session identifier for frequency capping.
render_context required Render Context Object Describes how the ad will be rendered in your app.
placements required array Array of placement objects (1-3). Length must match numAds.
.placement required string "above_response", "below_response", "inline_response", "left_response", "right_response"
.placement_id string Optional tracking ID for this ad slot.
max_ad_length number Max characters for ad text.
supports_markdown boolean Whether markdown is rendered.
supports_links boolean Whether clickable links are supported.
userId string Unique user identifier.
testAd boolean Returns a real ad without an impression id. Use for testing.
numAds number Number of ads to return (1-3). Must match placements length.
Field Type Description
device Device Object Device and location information.
ip required string IP address for geo-targeting. Enables location-based ads.
os string "macos", "windows", or "linux"
timezone string IANA timezone. Enables time-based targeting.
locale string Locale (e.g., "en-US"). Enables localized ads.
user User Object User profile information.
email string User's email for identity matching. Higher CPMs.
ide IDE Object IDE-specific context.
name string IDE name: "cursor", "vscode", "intellij"
session_duration_ms number Time since IDE opened. Helps with engagement-based targeting.
active_file_language string Current file language. Enables language-specific tool ads.

Example Request

{
  "messages": [
    { "role": "user", "content": "How do I set up authentication in my Express app?" }
  ],
  "sessionId": "session-ide-001",
  "userId": "user-dev-123",
  "numAds": 1,
  "testAd": true,
  "render_context": {
    "placements": [
      { "placement": "below_response" }
    ],
    "max_ad_length": 280,
    "supports_markdown": true,
    "supports_links": true
  },
  "user": {
    "email": "[email protected]"
  },
  "device": {
    "ip": "192.168.1.100",
    "os": "macos",
    "timezone": "America/New_York",
    "locale": "en-US"
  },
  "ide": {
    "name": "cursor",
    "session_duration_ms": 3600000,
    "active_file_language": "typescript"
  }
}

Example Response

{
  "ads": [
    {
      "adText": "Secure your Express app with Auth0 — enterprise-grade authentication in minutes.",
      "adId": "ad_ide123",
      "title": "Auth0 - Authentication Platform",
      "brandName": "Auth0",
      "url": "https://auth0.com",
      "favicon": "https://auth0.com/favicon.ico",
      "impUrl": "https://server.trygravity.ai/imp?grclid=...",
      "clickUrl": "https://server.trygravity.ai/click?grclid=...",
      "payout": 0.02
    }
  ],
  "numAds": 1,
  "totalPayout": 0.02
}

For: iOS apps, Android apps, React Native, Flutter

Request Fields

Field Type Description
messages required array Conversation context. Array of {role, content} objects.
sessionId required string Session identifier for frequency capping.
render_context required Render Context Object Describes how the ad will be rendered in your app.
placements required array Array of placement objects (1-3). Length must match numAds.
.placement required string "above_response", "below_response", "inline_response", "left_response", "right_response"
.placement_id string Optional tracking ID for this ad slot.
max_ad_length number Max characters for ad text.
supports_images boolean Whether images can be displayed. Enables rich ads.
supports_cta_button boolean Whether CTA buttons are supported.
userId string Unique user identifier.
testAd boolean Returns a real ad without an impression id. Use for testing.
numAds number Number of ads to return (1-3). Must match placements length.
Field Type Description
device Device Object Device and location information.
ip required string IP address for geo-targeting. Enables location-based ads.
ua string User agent (e.g., "MyApp/2.1.0 (iPhone; iOS 17.2)").
os string "iOS" or "Android". Enables platform-specific ads.
os_version string OS version (e.g., "17.2")
device_model string Device model (e.g., "iPhone 15 Pro"). Enables device targeting.
ifa string IDFA/GAID for attribution. Higher CPMs. Null if ATT denied.
timezone string IANA timezone. Enables time-based targeting.
locale string Device locale. Enables localized ads.
connection_type string "wifi" or "cellular"
user User Object User profile information.
email string User's email for identity matching. Higher CPMs.
subscription_tier string "free" or "premium". Premium users = higher value.
user_created_at string Account creation timestamp (ISO 8601). Helps identify engaged users.
user_interests array Array of interest tags. Enables interest-based targeting.
app App Object App-specific context.
version string Your app version.

Example Request

{
  "messages": [
    { "role": "assistant", "content": "I found several Italian restaurants nearby." },
    { "role": "user", "content": "Which one has the best pasta?" }
  ],
  "sessionId": "session-mobile-001",
  "userId": "user-app-456",
  "numAds": 1,
  "testAd": true,
  "render_context": {
    "placements": [
      { "placement": "inline_response" }
    ],
    "max_ad_length": 150,
    "supports_images": true,
    "supports_cta_button": true
  },
  "user": {
    "email": "[email protected]",
    "subscription_tier": "premium",
    "user_created_at": "2023-06-15T00:00:00Z",
    "user_interests": ["food", "dining", "travel"]
  },
  "device": {
    "ip": "198.51.100.23",
    "ua": "MyApp/2.1.0 (iPhone; iOS 17.2; Scale/3.00)",
    "os": "iOS",
    "os_version": "17.2",
    "device_model": "iPhone 15 Pro",
    "ifa": "6D92078A-8246-4BA4-AE5B-76104861E7DC",
    "timezone": "America/Los_Angeles",
    "locale": "en-US",
    "connection_type": "wifi"
  },
  "app": {
    "version": "2.1.0"
  }
}

Example Response

{
  "ads": [
    {
      "adText": "Craving authentic Italian? Get 20% off your first order at Bella Cucina.",
      "adId": "ad_mobile123",
      "title": "Bella Cucina - Italian Restaurant",
      "brandName": "Bella Cucina",
      "url": "https://bellacucina.com",
      "favicon": "https://bellacucina.com/favicon.ico",
      "impUrl": "https://server.trygravity.ai/imp?grclid=...",
      "clickUrl": "https://server.trygravity.ai/click?grclid=...",
      "payout": 0.02
    }
  ],
  "numAds": 1,
  "totalPayout": 0.02
}

For: Any platform — start here if you're unsure

Request Fields

Field Type Description
messages required array Conversation context. Array of {role, content} objects.
sessionId required string Session identifier for frequency capping.
render_context required Render Context Object Describes how the ad will be rendered in your app.
placements required array Array of placement objects (1-3). Length must match numAds.
.placement required string "above_response", "below_response", "inline_response", "left_response", "right_response"
.placement_id string Optional tracking ID for this ad slot.
max_ad_length number Max characters for ad text.
userId string Unique user identifier.
testAd boolean Returns a real ad without an impression id. Use for testing.
numAds number Number of ads to return (1-3). Must match placements length.
Field Type Description
device Device Object Device and location information.
ip required string IP address for geo-targeting. Enables location-based ads.
timezone string IANA timezone. Enables time-based targeting.
locale string Locale (e.g., "en-US"). Enables localized ads.
user User Object User profile information.
email string User's email for identity matching. Higher CPMs.

Example Request

{
  "messages": [
    { "role": "user", "content": "Where can I buy marathon gear?" }
  ],
  "sessionId": "session-general-001",
  "userId": "user-general-123",
  "numAds": 1,
  "testAd": true,
  "render_context": {
    "placements": [
      { "placement": "below_response" }
    ]
  }
}

Example Response

{
  "ads": [
    {
      "adText": "Run your best marathon yet. Shop premium running shoes at Nike.",
      "adId": "ad_general123",
      "title": "Nike Running",
      "brandName": "Nike",
      "url": "https://nike.com/running",
      "favicon": "https://nike.com/favicon.ico",
      "impUrl": "https://server.trygravity.ai/imp?grclid=...",
      "clickUrl": "https://server.trygravity.ai/click?grclid=...",
      "payout": 0.02
    }
  ],
  "numAds": 1,
  "totalPayout": 0.02
}

Response Reference

Response Fields

Field Type Description
adText string AI-generated ad copy tailored to the conversation.
adId string Unique ad identifier for tracking.
title string Ad title / headline.
brandName string Advertiser's brand name.
url string Landing page URL (for display).
favicon string Brand favicon URL.
impUrl string Impression tracking URL. Fire when ad is displayed.
clickUrl string Click tracking URL. Use as the anchor href.
payout number Your revenue in USD for this impression.
Important: Tracking

You must fire impUrl when the ad is displayed and use clickUrl as the link href. This ensures accurate billing and attribution.

Response Codes

200 Ad(s) matched and returned successfully. 204 No matching ads found (no body returned). This is normal. 401 Invalid or missing API key. 422 Validation error (e.g., missing sessionId, render_context, or numAds/placements mismatch). 429 Rate limit exceeded.

Rate Limits

Default: 1,000 requests per second. Contact support for higher limits.

Health Check

GET https://server.trygravity.ai/health

Public endpoint for load balancers and monitoring systems.

Response

{
  "status": "ok",
  "ready": true
}
Field Type Description
status string Always "ok" if the service is running.
ready boolean true when fully initialized and ready for traffic.

Usage

Support

Questions? Contact us at [email protected]