News WebSocket
News WebSocket Service¶
Overview¶
Bridge402's News WebSocket service provides real-time access to premium crypto news streams, bridged from Web2 sources to Web3 applications via x402 payments. This enables AI agents and decentralized applications to access professional-grade news feeds that were previously behind paywalls or subscription services.
The Bridge402 WebSocket API provides real-time access to crypto news streams. Access is controlled through x402 payments, ensuring only paying users can access the stream.
Connection Process¶
1. Create Session¶
First, create a session using the /connect endpoint:
curl -X POST "https://bridge402.tech/connect" \
  -H "X-PAYMENT: <base64-encoded-payment>" \
  -d "duration_min=10"
Response:
{
  "access_token": "eyJzZXNzaW9uX2lkIjoi...",
  "expires_at": 1703123456.789,
  "payment": {
    "verified": true,
    "settled": true,
    "txHash": "0x1234...",
    "network": "base"
  }
}
2. Connect to WebSocket¶
Use the access token to connect to the WebSocket stream:
Message Types¶
Connection Confirmation¶
When you first connect, you'll receive a confirmation message:
News Messages¶
Real-time news messages can be either Twitter/X posts or news articles. The message format varies based on the source type.
Twitter/X Post Format¶
{
  "title": "stacks.btc (@Stacks)",
  "body": "we're excited to introduce a new companion that will automatically deposit more bitcoin in your wallet every 2 weeks just for holding bitcoin on stacks and enrolling in dual stacking https://t.co/t8r1ZkhsJa",
  "icon": "https://pbs.twimg.com/profile_images/1764968185399267328/lrmnHOuN.jpg",
  "image": "https://pbs.twimg.com/media/G4njjP3bAAACG16.jpg",
  "urls": [],
  "mentions": [],
  "requireInteraction": true,
  "type": "direct",
  "link": "https://twitter.com/Stacks/status/1984367309054755272",
  "info": {
    "twitterId": "3285797414",
    "isReply": false,
    "isRetweet": false,
    "isQuote": false,
    "isSelfReply": false
  },
  "coin": "STX",
  "actions": [
    {
      "action": "BINFUT_STXUSDT",
      "title": "STXUSDT PERP",
      "icon": "https://news.treeofalpha.com/static/images/binance_icon.png"
    }
  ],
  "suggestions": [...],
  "time": 1761945009301,
  "_id": "1984367309054755272",
  "show_feed": true,
  "show_notif": true
}
News Article Format¶
{
  "title": "COINTELEGRAPH: MEXC apologizes to 'White Whale' trader over $3M freeze",
  "source": "Blogs",
  "url": "https://cointelegraph.com/news/mexc-white-whale-trader-token-freeze",
  "time": 1761945308076,
  "symbols": [],
  "en": "COINTELEGRAPH: MEXC apologizes to 'White Whale' trader over $3M freeze",
  "_id": "1761945308075CMatWWto3f",
  "suggestions": [],
  "delay": 5000
}
Common Fields:
| Field | Type | Description | 
|---|---|---|
title | 
string | Message/article title | 
time | 
number | Timestamp (milliseconds) | 
_id | 
string | Unique message identifier | 
Twitter/X Post Fields:
| Field | Type | Description | 
|---|---|---|
body | 
string | Post content/body text | 
icon | 
string | Profile icon/image URL | 
image | 
string | Optional attached image URL | 
link | 
string | Link to original Twitter/X post | 
coin | 
string | Primary coin/token mentioned | 
actions | 
array | Available trading actions (exchanges, pairs) | 
suggestions | 
array | Coin suggestions with exchange symbols | 
info | 
object | Twitter metadata (isReply, isRetweet, etc.) | 
News Article Fields:
| Field | Type | Description | 
|---|---|---|
source | 
string | News source name (e.g., "Blogs", "COINTELEGRAPH") | 
url | 
string | Link to original article | 
en | 
string | English title/description | 
symbols | 
array | Related trading symbols | 
suggestions | 
array | Coin suggestions | 
delay | 
number | Delay value (milliseconds) | 
Session Management Messages¶
Renewal Prompt (Halfway Point)¶
When you're halfway through your session:
{
  "type": "renewal_prompt",
  "message": "You're halfway through your session. Extend now to avoid interruption (POST /extend with X-SESSION and X-PAYMENT).",
  "expires_at": 1703123456,
  "seconds_remaining": 150,
  "docs": {
    "extend_endpoint": "/extend",
    "headers": ["X-SESSION: <your access_token>", "X-PAYMENT: <base64 x402>"]
  }
}
Expiry Warning (30 seconds before)¶
{
  "type": "expiry_soon",
  "message": "Session expires in ~30 seconds. Extend via /extend to stay connected.",
  "expires_at": 1703123456,
  "seconds_remaining": 25
}
Session Extended¶
When session is successfully extended:
{
  "type": "session_extended",
  "message": "Session extended without disconnecting.",
  "expires_at": 1703123456,
  "seconds_remaining": 300
}
Session Extension¶
Automatic Extension¶
The WebSocket client should automatically extend sessions when:
- Halfway Point: When 50% of session time has elapsed
 - Expiry Warning: When 30 seconds remain before expiry
 
Manual Extension¶
To manually extend a session:
curl -X POST "https://bridge402.tech/extend" \
  -H "X-SESSION: <your-access-token>" \
  -H "X-PAYMENT: <base64-encoded-payment>" \
  -d "duration_min=5"
Error Handling¶
WebSocket Error Codes¶
- 4000: General error
 - 4001: Invalid or expired token
 
Connection Issues¶
Handle these common scenarios:
- Token Expired: Reconnect with new session
 - Network Disconnect: Implement reconnection logic
 - Payment Required: Generate new payment and reconnect
 
Reconnection Strategy¶
class Bridge402Client {
  constructor(apiUrl, privateKey) {
    this.apiUrl = apiUrl;
    this.privateKey = privateKey;
    this.ws = null;
    this.session = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
  }
  async connect() {
    try {
      // Create session first
      this.session = await this.createSession();
      // Connect to WebSocket
      this.ws = new WebSocket(`${this.apiUrl}/stream?token=${this.session.access_token}`);
      this.ws.onopen = () => {
        console.log('Connected to Bridge402 stream');
        this.reconnectAttempts = 0;
      };
      this.ws.onmessage = (event) => {
        this.handleMessage(JSON.parse(event.data));
      };
      this.ws.onclose = (event) => {
        if (event.code === 4001) {
          // Token expired, create new session
          this.reconnect();
        } else {
          // Other error, attempt reconnection
          this.reconnect();
        }
      };
    } catch (error) {
      console.error('Connection failed:', error);
      this.reconnect();
    }
  }
  async reconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('Max reconnection attempts reached');
      return;
    }
    this.reconnectAttempts++;
    const delay = Math.pow(2, this.reconnectAttempts) * 1000; // Exponential backoff
    console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
    setTimeout(() => {
      this.connect();
    }, delay);
  }
  handleMessage(message) {
    if (message.type === 'renewal_prompt') {
      this.extendSession();
    } else if (message.type === 'expiry_soon') {
      this.extendSession();
    } else if (message.title) {
      // News message
      this.processNews(message);
    }
  }
  async extendSession() {
    try {
      const payment = await this.createPayment(5); // Extend by 5 minutes
      const response = await fetch(`${this.apiUrl}/extend`, {
        method: 'POST',
        headers: {
          'X-SESSION': this.session.access_token,
          'X-PAYMENT': payment,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ duration_min: 5 })
      });
      if (response.ok) {
        const data = await response.json();
        this.session.access_token = data.access_token;
        this.session.expires_at = data.expires_at;
        console.log('Session extended successfully');
      }
    } catch (error) {
      console.error('Failed to extend session:', error);
    }
  }
}
Best Practices¶
1. Session Management¶
- Always monitor session expiry
 - Implement automatic extension logic
 - Handle session renewal gracefully
 
2. Message Processing¶
- Process messages asynchronously
 - Implement message queuing for high-volume scenarios
 - Filter messages based on your needs
 
3. Error Handling¶
- Implement exponential backoff for reconnections
 - Log errors for debugging
 - Provide user feedback for connection issues
 
4. Performance¶
- Use connection pooling for multiple streams
 - Implement message batching if needed
 - Monitor memory usage for long-running connections
 
Rate Limits¶
- Connection Rate: 10 connections per minute per IP
 - Message Rate: No limit on incoming messages
 - Extension Rate: 1 extension per minute per session
 
Security Considerations¶
- Always use WSS (WebSocket Secure) in production
 - Validate all incoming messages
 - Implement proper authentication checks
 - Monitor for suspicious activity
 
Troubleshooting¶
Common Issues¶
- Connection Refused: Check API URL and network connectivity
 - Token Invalid: Verify session token format and expiry
 - Payment Failed: Check x402 payment format and network
 - Messages Not Received: Check WebSocket connection status
 
Debug Mode¶
Enable debug logging to troubleshoot issues:
// Enable WebSocket debug logging
WebSocket.debug = true;
// Or use browser dev tools
console.log('WebSocket state:', ws.readyState);
console.log('Session expiry:', new Date(session.expires_at * 1000));
Monitoring¶
Monitor these metrics:
- Connection uptime
 - Message processing rate
 - Session extension frequency
 - Error rates and types