Skip to main content
GET /v2/feed returns the last seven days of trade activity grouped by source message, newest first. Each group embeds the source post, the trader, the assets, and the events, so you can render it with no extra calls.

Read and page back

Terminal
Page back with meta.nextCursor as cursor. The feed never reaches past its seven-day window: to keep a longer history, store groups yourself and keep them current with since. The API reference lists every parameter and field.

Display the source text

source.text (and source.preview.text in messages) is the stored post: Telegram HTML or escaped X text. Sanitize it with an allowlist before you display it, and never insert it as raw HTML.

Stored X context

X sources include optional source.x with readable URL labels, reply context, and one quoted post. A quoted post carries its own source identity, timestamp, text, and uploaded attachments. It may be older than the feed window or come from an author who is not a Centaur trader. Referenced traders must have message visibility for your role and must not be muted; their signals need not be visible. quote.status: "unavailable" means no eligible stored parent can be shown. Present a generic “Quoted post unavailable” message and use its permalink when supplied. It does not distinguish missing, hidden, deleted, or protected content. Stored context does not track current availability on X. An unresolved reply uses “Replying to a post” and its tweet ID permalink when known. Render urls[].displayUrl as text, linking to the original urls[].url (t.co), never an expanded destination. attachmentUrls identifies a complete uploaded-image association. Only hide a terminal media URL after every associated image loads successfully; keep it on failure. Video, ambiguous media links, and ordinary URLs remain usable. Treat missing or null source.x as no context and replace prior enrichment on each successful refresh. Older producers can omit it; Telegram sources use null. Source text semantics remain unchanged, with no recursive quote or long-post expansion.

Poll for changes

since returns groups that changed after an earlier response. It follows when Centaur recorded events, not when the message was posted, so a late or retrospective event can bring back a group that is days old.
  1. Pass the latest meta.nextCursor as since.
  2. Upsert each returned group: replace the stored group with the same id as a whole. A group carries all its current events, including ones you saw before.
  3. While the response has hasMore: true, call again with its nextCursor as since.
  4. Store the newest nextCursor. Every successful poll returns one, even with no groups.
Event IDs can be assigned before concurrent transactions commit. To catch a late commit, keep the token from before your latest poll and replay it once on the next cycle. Merge those results by group id too, and keep moving forward with the newest token. since never reports a deleted group and is not a source-enrichment change stream. A parent or attachment arriving later does not advance the event cursor. Re-read the relevant bounded feed window to refresh source context and reflect removals. Hosted widgets refresh their latest and retained posts together, updating content in place on the next successful visible-tab poll, normally every 25–30 seconds. Hidden tabs, backoff, and offline operation have no wall-clock freshness guarantee.

What the feed shows

The feed drops events that have no evidence in their message, or that duplicate the message’s real event:
  • assumed and auto-generated closes
  • instant opens created at a position’s close
  • assumed opens when the same message has another event for the same asset
  • positions that lasted 60 seconds or less, and their events
A group with no events left is dropped. A lone inferred open still forms a group, with assumed: true. A group appears only when you may read both the trader’s signals and their messages, so /v2/events can return a trader who never appears in the feed. Centaur may also leave sources out of the feed for editorial or quality reasons. Feed events carry no performance: use positions and stats for that.

Freshness

The default first page, with no filters, can reuse a result up to 10 minutes old: meta.dataComputedAt says when it was read. Once that result is 60 seconds old, a request starts a refresh but still gets the existing page. A cached page holding a message outside the seven-day window is never served. Cached quotes and exposed reply identities are rechecked before serving; revoked message visibility, muted accounts, missing parents, or changed parent ownership force a live read. Filtered requests, explicit time bounds, other page sizes, later pages, and since polls always read live, over REST and MCP.
Last modified on November 4, 2026