· Nacho Coll · Guides · 8 min read
X Alerts API: Programmatic Subscriptions and Notification History
Build custom integrations on top of WALLAWHATS. Add and remove X subscriptions, route alerts to channels, pull notification history — all via REST.

When real-time X (Twitter) alerts become mission-critical for your business, manual dashboard management hits a wall. Whether you’re building customer intelligence dashboards, automating brand monitoring workflows, or creating custom notification systems for trading desks, you need programmatic control over your X alert subscriptions.
WALLAWHATS provides a REST API that lets you create, manage, and audit X alert subscriptions without touching the web interface. Add or remove monitored accounts, pull notification history with delivery status, and integrate real-time X alerts into any system that speaks HTTP.

Why Use the WALLAWHATS API?
The dashboard works great for manual workflows, but API access unlocks automation scenarios that scale beyond human management:
Customer Intelligence Platforms: Automatically subscribe to newly identified competitor executives, product leads, or industry analysts as they’re discovered through research tools or CRM integrations.
Trading and Financial Workflows: Programmatically monitor regulatory accounts, CEO handles, or sector-specific journalists based on portfolio changes or market events—without manual subscription management.
Brand Monitoring at Scale: Add or remove brand mention tracking as new campaigns launch, products ship, or crisis situations develop.
Multi-Tenant SaaS Applications: White-label real-time X monitoring for your customers, with programmatic subscription management behind the scenes.
Compliance and Audit Systems: Pull complete notification history with delivery status for regulatory reporting, internal audit trails, or SLA monitoring.
API Authentication and Access
Every WALLAWHATS plan includes API access with scaling key quotas:
- Free: 1 API key
- Pro: 1 API key
- Pro+: 2 API keys
- Business: 5 API keys
- Enterprise: 20 API keys
Authentication uses the x-api-key header (not Authorization: Bearer). Generate your keys from the dashboard’s API section, and treat them like passwords—they carry full account privileges.
curl -H "x-api-key: your_api_key_here" \
https://api.wallawhats.com/subscriptionsCore API Endpoints
The WALLAWHATS API provides five main resource groups for building integrations:
Subscription Management
Create a new subscription:
POST /subscriptions
Content-Type: application/json
x-api-key: your_api_key_here
{
"xUsername": "elonmusk"
}List all subscriptions:
GET /subscriptions
x-api-key: your_api_key_hereRemove a subscription:
DELETE /subscriptions/elonmusk
x-api-key: your_api_key_hereNote the delete endpoint takes the X handle as a path parameter—not an internal subscription ID.
Notification History and Audit
Pull notification history with delivery status:
GET /notifications?from=1704067200000&to=1704153600000
x-api-key: your_api_key_hereThe notifications endpoint returns paginated results with each row representing one alert delivered to one channel. Status values include:
queued: Alert accepted, waiting for deliverysent: Dispatched to the channel providerdelivered: Confirmed received by the destinationread: Opened by the recipient (WhatsApp only, requires read receipts enabled)failed: Delivery attempt unsuccessful
Channel Management
List configured channels:
GET /channels
x-api-key: your_api_key_hereAdd a new channel:
POST /channels
Content-Type: application/json
x-api-key: your_api_key_here
{
"type": "email",
"destination": "alerts@yourcompany.com"
}Remove a channel:
DELETE /channels/channel_id_here
x-api-key: your_api_key_hereTweet Snapshots
Access the snapshot gallery:
GET /snapshots
x-api-key: your_api_key_hereDelete a specific snapshot:
DELETE /snapshots/tweet_id_here
x-api-key: your_api_key_hereBuilding Integrations: Code Examples
Node.js Integration
Here’s a Node.js example that adds a subscription and polls for new notifications:
const axios = require('axios');
class WallaWhatsClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = 'https://api.wallawhats.com';
}
async addSubscription(xUsername) {
try {
const response = await axios.post(
`${this.baseURL}/subscriptions`,
{ xUsername },
{ headers: { 'x-api-key': this.apiKey } }
);
return response.data;
} catch (error) {
throw new Error(`Failed to add subscription: ${error.response?.data?.message || error.message}`);
}
}
async getNotifications(from, to, lastKey = null) {
try {
let url = `${this.baseURL}/notifications?from=${from}&to=${to}`;
if (lastKey) url += `&lastKey=${lastKey}`;
const response = await axios.get(url, {
headers: { 'x-api-key': this.apiKey }
});
return response.data;
} catch (error) {
throw new Error(`Failed to fetch notifications: ${error.response?.data?.message || error.message}`);
}
}
async listSubscriptions() {
try {
const response = await axios.get(
`${this.baseURL}/subscriptions`,
{ headers: { 'x-api-key': this.apiKey } }
);
return response.data;
} catch (error) {
throw new Error(`Failed to list subscriptions: ${error.response?.data?.message || error.message}`);
}
}
}
// Usage example
async function monitorCompetitor() {
const client = new WallaWhatsClient('your_api_key_here');
// Add a new subscription
await client.addSubscription('vercel');
console.log('Now monitoring @vercel');
// Check recent notifications
const oneDayAgo = Date.now() - (24 * 60 * 60 * 1000);
const notifications = await client.getNotifications(oneDayAgo, Date.now());
console.log(`Found ${notifications.items.length} recent alerts`);
notifications.items.forEach(notification => {
console.log(`${notification.xUsername}: ${notification.status} at ${notification.timestamp}`);
});
}Python Integration
For Python workflows, here’s a class that handles subscription management and notification polling:
import requests
import time
from datetime import datetime, timedelta
class WallaWhatsAPI:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://api.wallawhats.com'
self.headers = {'x-api-key': api_key}
def add_subscription(self, x_username):
"""Add a new X account to monitor"""
response = requests.post(
f'{self.base_url}/subscriptions',
json={'xUsername': x_username},
headers=self.headers
)
response.raise_for_status()
return response.json()
def remove_subscription(self, x_username):
"""Remove an X account from monitoring"""
response = requests.delete(
f'{self.base_url}/subscriptions/{x_username}',
headers=self.headers
)
response.raise_for_status()
return response.status_code == 200
def get_notifications(self, from_ms, to_ms, last_key=None):
"""Fetch notification history with pagination"""
params = {'from': from_ms, 'to': to_ms}
if last_key:
params['lastKey'] = last_key
response = requests.get(
f'{self.base_url}/notifications',
params=params,
headers=self.headers
)
response.raise_for_status()
return response.json()
def get_all_notifications(self, from_ms, to_ms):
"""Fetch all notifications in a time range, handling pagination"""
all_notifications = []
last_key = None
while True:
batch = self.get_notifications(from_ms, to_ms, last_key)
all_notifications.extend(batch['items'])
if not batch.get('lastKey'):
break
last_key = batch['lastKey']
return all_notifications
def list_subscriptions(self):
"""Get all current subscriptions"""
response = requests.get(
f'{self.base_url}/subscriptions',
headers=self.headers
)
response.raise_for_status()
return response.json()
# Example: Daily audit report
def generate_daily_report():
api = WallaWhatsAPI('your_api_key_here')
# Get yesterday's notifications
end_time = int(time.time() * 1000)
start_time = end_time - (24 * 60 * 60 * 1000)
notifications = api.get_all_notifications(start_time, end_time)
# Group by account and status
report = {}
for notification in notifications:
account = notification['xUsername']
status = notification['status']
if account not in report:
report[account] = {'total': 0, 'delivered': 0, 'failed': 0}
report[account]['total'] += 1
if status in ['delivered', 'read']:
report[account]['delivered'] += 1
elif status == 'failed':
report[account]['failed'] += 1
# Print summary
print(f"Daily Alert Report - {datetime.now().strftime('%Y-%m-%d')}")
print("-" * 50)
for account, stats in report.items():
success_rate = (stats['delivered'] / stats['total']) * 100 if stats['total'] > 0 else 0
print(f"@{account}: {stats['total']} alerts, {success_rate:.1f}% delivered")Understanding Channel Routing
WALLAWHATS uses a global channel routing model—every alert from every subscription fans out to all enabled and verified channels. You can’t route specific accounts to specific destinations via the API (like “@elonmusk → WhatsApp, @vercel → email”).
Channel selection happens at the account level on the Channels page. When you add a channel via API, it becomes available for all alerts once verified. When you remove a channel, it stops receiving alerts from all subscriptions.
This design simplifies automation while preventing alert fragmentation. Your integration code doesn’t need to track per-subscription routing rules—just manage which accounts to monitor and which channels to enable.
Rate Limits and Velocity Caps
WALLAWHATS implements user-level velocity caps to prevent alert spam during high-activity periods:
- Free: 2 alerts/hour
- Pro: 5 alerts/hour
- Pro+: 15 alerts/hour
- Business: 30 alerts/hour
- Enterprise: 100 alerts/hour
When velocity caps are exceeded, additional tweets are buffered into digest messages and delivered every 15 minutes. Your API integration will see these as separate notification records—one for the immediate alert, and one for each digest batch.
The API itself doesn’t impose separate rate limits on subscription management or notification queries. However, avoid hammering the endpoints with unnecessary requests—cache subscription lists locally and batch notification queries efficiently.
Error Handling and Troubleshooting
Common API error patterns and how to handle them:
Authentication failures (401):
- Verify your API key is correct and hasn’t been revoked
- Ensure you’re using the
x-api-keyheader, notAuthorization
Subscription conflicts (409):
- Account already monitored: The subscription exists, treat as success
- Account protected/private: WALLAWHATS refuses these by design
Rate limiting (429):
- Back off exponentially before retrying
- Check if you’re approaching plan limits on monitored accounts
Channel verification issues:
- New channels require OTP verification before receiving alerts
- Programmatically added channels won’t work until the user completes verification
Monitoring and Alerting Your Integrations
Since WALLAWHATS becomes critical infrastructure when integrated into business workflows, monitor your integration health:
Subscription Drift Detection:
// Check if expected subscriptions are still active
async function auditSubscriptions(expectedHandles) {
const current = await client.listSubscriptions();
const currentHandles = current.map(s => s.xUsername);
const missing = expectedHandles.filter(h => !currentHandles.includes(h));
if (missing.length > 0) {
console.warn(`Missing subscriptions: ${missing.join(', ')}`);
}
return missing;
}Delivery Success Rate Monitoring:
def check_delivery_health():
# Check last 6 hours
end_time = int(time.time() * 1000)
start_time = end_time - (6 * 60 * 60 * 1000)
notifications = api.get_all_notifications(start_time, end_time)
if not notifications:
return None
delivered = sum(1 for n in notifications if n['status'] in ['delivered', 'read'])
total = len(notifications)
success_rate = (delivered / total) * 100
if success_rate < 95:
# Alert your ops team
print(f"WARNING: Delivery success rate dropped to {success_rate:.1f}%")
return success_rateIntegration Patterns and Best Practices
Webhook-Style Processing: While WALLAWHATS doesn’t provide webhooks directly, you can poll the notifications endpoint for new alerts and process them in near-real-time:
async function pollForNewAlerts() {
const lastCheck = localStorage.getItem('lastNotificationCheck') || Date.now() - 300000;
const now = Date.now();
const notifications = await client.getNotifications(lastCheck, now);
for (const notification of notifications.items) {
if (notification.status === 'delivered') {
// Process the alert - send to Slack, update database, etc.
await processAlert(notification);
}
}
localStorage.setItem('lastNotificationCheck', now);
}
// Poll every 30 seconds
setInterval(pollForNewAlerts, 30000);Conditional Subscription Management: Dynamically add or remove subscriptions based on external triggers:
def update_competitor_monitoring(portfolio_companies):
"""Update X monitoring based on current portfolio"""
current_subs = {s['xUsername'] for s in api.list_subscriptions()}
# Accounts we should be monitoring
target_accounts = set()
for company in portfolio_companies:
if company.get('ceo_twitter_handle'):
target_accounts.add(company['ceo_twitter_handle'])
if company.get('company_twitter_handle'):
target_accounts.add(company['company_twitter_handle'])
# Add missing subscriptions
for account in target_accounts - current_subs:
try:
api.add_subscription(account)
print(f"Started monitoring @{account}")
except Exception as e:
print(f"Failed to add @{account}: {e}")
# Remove outdated subscriptions
for account in current_subs - target_accounts:
api.remove_subscription(account)
print(f"Stopped monitoring @{account}")The WALLAWHATS API transforms real-time X alerts from a manual dashboard tool into a programmable infrastructure component. Whether you’re building custom intelligence workflows, automating brand monitoring, or creating white-label notification services, the API provides the control and audit capabilities needed for production integration.
Looking to expand your monitoring beyond competitors? Check out our guide on monitoring crypto Twitter for market signals or learn how journalists use WALLAWHATS for real-time source monitoring.
Never miss an important post again. Create a free account — 1 WhatsApp number, real-time alerts, no credit card required.
