Grok API Developer Guide: Build Real-Time News and Sentiment Analysis Applications
What Makes the Grok API Unique for Real-Time Applications
The Grok API from xAI provides something no other major LLM API offers natively: real-time access to X/Twitter data combined with web search and reasoning capabilities. While OpenAI and Anthropic APIs work with training data and optional web browsing, Grok’s API has direct, real-time access to the X firehose — making it the only LLM API that can answer “what are people saying about [topic] right now?” with actual current data.
This makes the Grok API uniquely suited for:
- News monitoring: tracking breaking stories as they develop
- Sentiment analysis: measuring public opinion on products, brands, or events in real time
- Trend detection: identifying emerging topics before they hit mainstream media
- Competitive intelligence: tracking competitor mentions, launches, and customer reactions
- Crisis monitoring: detecting negative sentiment spikes that require immediate response
Getting Started with the Grok API
API Access Setup
import requests
XAI_API_KEY = "your-xai-api-key"
BASE_URL = "https://api.x.ai/v1"
def grok_query(prompt, model="grok-2", search=True):
response = requests.post(
f"{BASE_URL}/chat/completions",
headers={
"Authorization": f"Bearer {XAI_API_KEY}",
"Content-Type": "application/json"
},
json={
"model": model,
"messages": [
{"role": "system", "content": "You are a real-time news and sentiment analyst. Always cite sources and include timestamps."},
{"role": "user", "content": prompt}
],
"search": search # Enable real-time web + X search
}
)
return response.json()
Model Options
| Model | Speed | Capability | Best For |
|---|---|---|---|
| grok-2 | Fast | Strong reasoning + search | Most applications |
| grok-2-mini | Very fast | Lighter, still good search | High-volume monitoring |
The Search Parameter
The search parameter is what makes Grok unique:
search: true— Grok searches the live web and X/Twitter before respondingsearch: false— Grok responds from its training data only (like other LLMs)
For real-time applications, always set search: true.
Building a News Monitoring System
Basic News Monitor
class NewsMonitor:
def __init__(self, api_key, topics):
self.api_key = api_key
self.topics = topics
self.history = {}
def check_topic(self, topic):
prompt = f"""Search for the latest news about "{topic}" from the
past 4 hours. Return a structured summary:
1. BREAKING: Any breaking news or major developments
2. KEY STORIES: Top 3 stories with source and timestamp
3. X/TWITTER: Most-discussed aspects on X right now
4. SENTIMENT: Overall public sentiment (positive/negative/mixed)
5. NOTABLE VOICES: Any influential figures commenting
If nothing significant happened, say "No major developments."
"""
result = grok_query(prompt)
return self._parse_result(result, topic)
def run_cycle(self):
alerts = []
for topic in self.topics:
result = self.check_topic(topic)
if result["has_breaking_news"]:
alerts.append(result)
self.history[topic] = result
return alerts
# Usage
monitor = NewsMonitor(
api_key="your-key",
topics=["AI regulation", "OpenAI", "tech layoffs", "cryptocurrency"]
)
alerts = monitor.run_cycle()
Scheduled Monitoring with Alerts
import schedule
import time
def check_and_alert():
alerts = monitor.run_cycle()
for alert in alerts:
send_slack_alert(alert) # or email, SMS, etc.
# Check every 30 minutes
schedule.every(30).minutes.do(check_and_alert)
while True:
schedule.run_pending()
time.sleep(60)
Building a Sentiment Analysis System
Real-Time Brand Sentiment Tracker
class SentimentTracker:
def __init__(self, api_key, brand_name):
self.api_key = api_key
self.brand = brand_name
self.sentiment_log = []
def analyze_current_sentiment(self):
prompt = f"""Analyze the current public sentiment about
"{self.brand}" based on X/Twitter posts and recent web mentions
from the past 24 hours.
Provide:
1. OVERALL SENTIMENT: Score from -100 (extremely negative) to
+100 (extremely positive)
2. VOLUME: Approximate number of mentions (low/medium/high/viral)
3. TOP POSITIVE THEMES: What people like (with example posts)
4. TOP NEGATIVE THEMES: What people complain about (with example posts)
5. SENTIMENT SHIFT: Compared to typical sentiment, is it trending
more positive or negative?
6. RISK ASSESSMENT: Any emerging issues that could escalate?
Return as JSON format for programmatic parsing."""
result = grok_query(prompt)
parsed = self._parse_sentiment(result)
self.sentiment_log.append({
"timestamp": datetime.now().isoformat(),
"data": parsed
})
return parsed
def detect_anomaly(self):
if len(self.sentiment_log) < 10:
return None # Need baseline data
recent = self.sentiment_log[-1]["data"]["score"]
baseline = sum(s["data"]["score"] for s in self.sentiment_log[-10:-1]) / 9
deviation = abs(recent - baseline)
if deviation > 30: # 30-point swing
return {
"type": "sentiment_anomaly",
"current": recent,
"baseline": baseline,
"deviation": deviation,
"direction": "positive" if recent > baseline else "negative"
}
return None
Multi-Brand Comparison
def compare_brands(brands):
prompt = f"""Compare public sentiment for these brands on X/Twitter
right now: {', '.join(brands)}
For each brand, provide:
- Sentiment score (-100 to +100)
- Discussion volume (1-10 scale)
- Top talking points (2-3 bullet points)
- Notable recent mentions from influential accounts
Present as a comparison table. Note any brand that is trending
significantly different from its usual sentiment."""
return grok_query(prompt)
Building a Trend Detection System
Emerging Trend Identifier
class TrendDetector:
def __init__(self, api_key, domain):
self.api_key = api_key
self.domain = domain
def scan_for_trends(self):
prompt = f"""Scan X/Twitter and web sources for emerging trends
in the {self.domain} space that started gaining traction in the
past 48 hours.
I need trends that are:
- NEW (not ongoing stories from last week)
- GROWING (mention volume is increasing)
- RELEVANT to {self.domain}
For each trend found:
1. TREND NAME: Short descriptive title
2. SIGNAL STRENGTH: 1-10 (1 = early whisper, 10 = mainstream)
3. GROWTH RATE: How fast is discussion increasing?
4. KEY SOURCES: Who started talking about this?
5. IMPLICATIONS: Why this matters for {self.domain}
6. PREDICTED TRAJECTORY: Will this grow or fade?
Return maximum 5 trends, ranked by signal strength."""
return grok_query(prompt)
# Usage
detector = TrendDetector(
api_key="your-key",
domain="enterprise SaaS"
)
trends = detector.scan_for_trends()
Trend Comparison Over Time
def track_trend_evolution(trend_name, days=7):
prompt = f"""Track how the conversation about "{trend_name}" has
evolved over the past {days} days on X/Twitter and the web.
Show:
1. Day-by-day volume estimate
2. How the narrative has shifted
3. Key inflection points (what caused volume spikes?)
4. Current status: still growing, peaked, or declining?
5. Geographic distribution: where is the conversation happening?
Include specific X posts that marked turning points in the
conversation."""
return grok_query(prompt)
Production Deployment
Rate Limiting and Error Handling
from tenacity import retry, wait_exponential, stop_after_attempt
import time
class GrokClient:
def __init__(self, api_key, requests_per_minute=30):
self.api_key = api_key
self.rpm_limit = requests_per_minute
self.request_times = []
def _throttle(self):
now = time.time()
self.request_times = [t for t in self.request_times if now - t < 60]
if len(self.request_times) >= self.rpm_limit:
wait_time = 60 - (now - self.request_times[0])
time.sleep(max(0, wait_time))
self.request_times.append(time.time())
@retry(wait=wait_exponential(min=2, max=30), stop=stop_after_attempt(3))
def query(self, prompt, model="grok-2"):
self._throttle()
response = requests.post(
f"{BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {self.api_key}"},
json={
"model": model,
"messages": [{"role": "user", "content": prompt}],
"search": True
},
timeout=30
)
if response.status_code == 429:
raise Exception("Rate limited")
response.raise_for_status()
return response.json()
Structured Output Parsing
import json
def parse_structured_response(response_text):
"""Extract JSON from Grok's response for programmatic use."""
try:
# Try to find JSON block in the response
if "```json" in response_text:
json_str = response_text.split("```json")[1].split("```")[0]
return json.loads(json_str)
# Try direct JSON parse
return json.loads(response_text)
except (json.JSONDecodeError, IndexError):
# Fallback: return raw text
return {"raw_text": response_text, "parsed": False}
Caching Strategy
from functools import lru_cache
from datetime import datetime
class TimedCache:
def __init__(self, ttl_seconds=300):
self.cache = {}
self.ttl = ttl_seconds
def get(self, key):
if key in self.cache:
entry = self.cache[key]
if (datetime.now() - entry["time"]).seconds < self.ttl:
return entry["value"]
del self.cache[key]
return None
def set(self, key, value):
self.cache[key] = {"value": value, "time": datetime.now()}
Cache durations for real-time applications:
- Breaking news queries: 5-10 minutes
- Sentiment snapshots: 15-30 minutes
- Trend analysis: 1-2 hours
- Historical comparisons: 4-24 hours
Cost Optimization
Token Usage by Query Type
| Query Type | Avg Input Tokens | Avg Output Tokens | Search Overhead |
|---|---|---|---|
| Quick news check | 100-200 | 300-500 | Low |
| Sentiment analysis | 200-400 | 500-1000 | Medium |
| Trend detection | 200-300 | 800-1500 | High |
| Deep research | 300-500 | 1500-3000 | High |
Cost Reduction Strategies
- Use
grok-2-minifor high-volume, simple queries (news checks) - Use
grok-2for complex analysis (sentiment, trends) - Cache aggressively — identical queries within TTL should not hit the API
- Batch related queries into single prompts where possible
- Set
max_tokensto prevent unnecessarily long responses
Frequently Asked Questions
How real-time is Grok’s X/Twitter data?
Grok has access to X posts within minutes of posting. For trending topics, data freshness is typically 5-15 minutes. For lower-volume topics, there may be a slight delay.
Can I access historical X/Twitter data through Grok?
Grok can reference historical posts, but its primary strength is real-time and recent data. For deep historical analysis, combine Grok with the X API’s historical search endpoints.
Is the Grok API compatible with OpenAI’s SDK?
The Grok API follows the OpenAI chat completions format. You can use the OpenAI Python SDK by changing the base_url to xAI’s endpoint and using your xAI API key.
What are the rate limits?
Rate limits depend on your plan tier. Standard plans typically allow 30-60 requests per minute. Check the xAI developer documentation for current limits.
Can I filter Grok’s search to specific sources or regions?
Currently, the search parameter is binary (on/off). You can guide source selection through your prompt (“focus on US news sources” or “check only tech industry publications”). Fine-grained source filtering may be added in future API versions.
Does Grok API pricing include search costs?
Search-enabled queries cost more tokens than non-search queries due to the additional processing. Check xAI’s current pricing page for the exact multiplier.