Skip to content
Velo

Fetch News

Fetch historical news

Call news.stories() with a millisecond timestamp to describe a request for stories published after that time, then pass it to velo.query() to execute it.

const velo = new Velo({ apiKey: process.env.VELO_API_KEY! });
const begin = Date.now() - 24 * 60 * 60 * 1_000;
const stories = await velo.query(news.stories({ begin }));
 
for (const story of stories) {
  console.log(story.headline);
}

Omit begin to fetch every available story:

const stories = await velo.query(news.stories());

Watch news in real-time

Describe the subscription with news.feed() and execute it with velo.watch(), which opens the WebSocket and resolves once the subscription is live.

const velo = new Velo({ apiKey: process.env.VELO_API_KEY! });
const watcher = await velo.watch(news.feed(), {
  on: {
    story: (story) => {
      console.log('New story:', story.headline);
    },
    edit: (story) => {
      console.log('Edited story:', story.headline);
    },
    delete: ({ id }) => {
      console.log('Deleted story:', id);
    },
    error: (error) => {
      console.error('News watcher error:', error);
    },
    close: ({ code, reason, wasClean }) => {
      console.log('News watcher closed:', { code, reason, wasClean });
    },
  },
});

To handle every event in one place, pass a single function instead of a map and switch on type:

const watcher = await velo.watch(news.feed(), {
  on: (event) => {
    switch (event.type) {
      case 'story':
      case 'edit':
        console.log(event.type, event.event.headline);
        break;
      case 'delete':
        console.log('Deleted story:', event.event.id);
        break;
    }
  },
});

Result types

Both stories() results and the watcher's story and edit events use the same story shape. An example of a story:

{
  "id": 1646,
  "time": 1765554594943,
  "effectiveTime": 1765554594943,
  "effectivePrice": 29.058,
  "headline": "Hyperliquid To Introduce Portfolio Margin",
  "source": "Team",
  "priority": 2,
  "coins": ["HYPE"],
  "summary": "Portfolio margin is coming.",
  "link": "https://t.me/hyperliquid_announcements"
}

The type of the story objects is the NewsStory type:

interface NewsStory {
  id: number;
  time: number;
  effectiveTime: number;
  effectivePrice: number | null;
  headline: string;
  source: string | null;
  priority: number;
  coins: string[];
  summary: string | null;
  link: string | null;
}

where time and effectiveTime are Unix timestamps in milliseconds.

The other watcher events have these payloads:

EventPayload
delete{ id: number }
errorVeloError
close{ code: number; reason: string; wasClean: boolean }