NEW: Live arbitrage across 10+ prediction markets.Arbitrage →
← Index
APIOct 15, 2026

Polymarket Comments API (2026): Read Market Comments in Code

Polymarket Comments API (2026): Read Market Comments in Code

The Short Answer

Polymarket serves comments through Gamma's public GET https://gamma-api.polymarket.com/comments, with parent_entity_type (Event or Series) and parent_entity_id both required. Each request returns up to 100 top-level comments, newest first by default, with their replies placed right after them. Every comment carries the author's profile, and get_positions=true adds what the author holds. GET /comments/{id} returns a whole thread and GET /comments/user_address/{address} returns one user's comments. No API key is needed. Live comment streaming is being retired, so plan to poll. In our checks on 3 October 2026, the Brazil presidential election event led all open events with more than 21,800 comments.

Key Takeaways

  • parent_entity_type accepts Event, Series or PerpsAsset, case-sensitive. The live API rejects market, even though the spec lists it.
  • Events that belong to a series keep their comments on the series, so read the series id from the event first.
  • limit counts top-level comments, at most 100. Replies come on top, one level deep, oldest first under their parent.
  • userAddress is the commenter's base address, not the proxy wallet. Use profile.proxyWallet for Data API lookups.
  • Polymarket is retiring live comment and reaction streaming without a replacement, so poll, and re-read threads to catch new replies.

How do you get comments for a Polymarket market?

Comments attach to events and series, not to individual markets. Pass the event id as the parent:

curl -s "https://gamma-api.polymarket.com/comments?parent_entity_type=Event&parent_entity_id=45915&limit=20&order=createdAt&ascending=false"

The response is a plain array. A top-level comment and its first reply look like this, trimmed:

[
  {
    "id": "3279728",
    "body": "...",
    "parentEntityType": "Event",
    "parentEntityID": 45915,
    "userAddress": "0x...",
    "createdAt": "2026-10-02T18:47:11.434762Z",
    "reactionCount": 0,
    "reportCount": 0,
    "profile": { "name": "...", "pseudonym": "...", "proxyWallet": "0x...", "baseAddress": "0x..." }
  },
  {
    "id": "3279740",
    "body": "...",
    "parentCommentID": "3279728",
    "replyAddress": "0x...",
    "createdAt": "2026-10-02T19:03:48.405527Z"
  }
]

Comment ids are strings and parentEntityID is a number. Comments with reactions also carry a reactions array, where each entry has a reactionType such as HEART and the reactor's address, and comments with a GIF carry a media array with the provider and URL. Leave out either parent parameter and Gamma returns a 422 saying a required query parameter is missing.

What parameters does the comments endpoint take?

ParameterWhat it does
parent_entity_typeEvent, Series or PerpsAsset, case-sensitive
parent_entity_idThe numeric event or series id
limit, offsetTop-level comments per page, at most 100 in our checks, and how many to skip
order, ascendingSort fields, comma-separated, such as createdAt or reactionCount
get_positionsAdds the author's positions in that event, or across the series, to profile.positions
holders_onlyReturns only comments from authors who hold a position

Without order, comments came back newest first in our checks. order=reactionCount&ascending=false surfaced the most-reacted comments instead, led by one with 70 reactions. Requests are limited to 200 per 10 seconds, and responses carried Cache-Control: public, max-age=90.

Why does an event return no comments?

Usually because it belongs to a series. Events in a series, such as each Fed decision or each month's Bitcoin price ladder, keep their comments on the series. In our checks, the October 2026 Fed decision event returned an empty array as an Event and showed a commentCount of 0, while its FOMC series, id 35, held 9,601 comments. The same held for a monthly Bitcoin series and a Dota 2 series.

The fix is to read the event first. When its series array has an entry, query parent_entity_type=Series with that series id. Each series entry also carries its own commentCount, so you know what to expect before paging.

How do threads and replies work?

Threads are one level deep. A reply carries parentCommentID, pointing at a top-level comment, and in a sample of 104 replies none pointed at another reply. replyAddress names the person being answered: it matched the top-level author in 72 of those replies, and most of the rest pointed at another person in the same thread.

Each reply sits directly after its parent in the array, oldest first, and limit counts only top-level comments. Asking for 100 returned 204 rows: 100 top-level comments and 104 replies. GET /comments/{id} returns the whole thread, parent and replies, whether you pass the parent's id or a reply's.

That ordering has a catch for anyone polling. Threads sort by the top-level comment's time, so a new reply to an older thread lands on a later page. In our checks, pages 2 and 3 held replies posted after the oldest thread on page 1. Re-read the threads you care about by id instead of relying on the first page.

How do you read commenter profiles and positions?

Every comment embeds a profile with name, pseudonym, displayUsernamePublic, bio, proxyWallet, baseAddress and profileImage. Two addresses are in play. The comment's userAddress equaled profile.baseAddress in all 204 rows we checked and never the proxy wallet. GET /comments/user_address/{address} wants that base address too: for four of four users, the base address returned their comments and the proxy wallet returned an empty list.

The proxy wallet is the one the Data API uses for positions and trades, as explained in our Polymarket proxy wallet guide. Gamma's /public-profile?address= accepts either address and returns proxyWallet, createdAt and the display name.

With get_positions=true, profile.positions lists tokenId and positionSize. The size is in base units, so divide by 1,000,000: in five checks it matched the Data API's share count for the same wallet and token. This builds labeled threads for an event on Node 18 or newer:

const GAMMA = 'https://gamma-api.polymarket.com';

async function getJson(url) {
  const res = await fetch(url);
  if (!res.ok) throw new Error(`${url} returned ${res.status}`);
  return res.json();
}

async function commentThreads(eventSlug, limit = 20) {
  const event = await getJson(`${GAMMA}/events/slug/${eventSlug}`);
  const series = event.series?.[0];
  const parent = series ? { type: 'Series', id: series.id } : { type: 'Event', id: event.id };

  // Label each outcome token so a commenter's position reads as words.
  const tokenLabel = new Map();
  for (const market of event.markets ?? []) {
    const tokens = JSON.parse(market.clobTokenIds ?? '[]');
    const outcomes = JSON.parse(market.outcomes ?? '[]');
    tokens.forEach((token, i) => tokenLabel.set(token, `${market.groupItemTitle || market.question} ${outcomes[i]}`));
  }

  const url = new URL('/comments', GAMMA);
  url.searchParams.set('parent_entity_type', parent.type);
  url.searchParams.set('parent_entity_id', parent.id);
  url.searchParams.set('limit', String(limit));
  url.searchParams.set('order', 'createdAt');
  url.searchParams.set('ascending', 'false');
  url.searchParams.set('get_positions', 'true');
  const comments = await getJson(url);

  const threads = new Map();
  for (const c of comments) if (!c.parentCommentID) threads.set(c.id, { ...c, replies: [] });
  for (const c of comments) if (c.parentCommentID) threads.get(c.parentCommentID)?.replies.push(c);

  return [...threads.values()].map((t) => ({
    author: t.profile?.name || t.profile?.pseudonym || t.userAddress,
    holds: (t.profile?.positions ?? []).map(
      (p) => `${Math.round(Number(p.positionSize) / 1e6)} ${tokenLabel.get(p.tokenId) ?? 'other market'}`,
    ),
    text: t.body,
    reactions: t.reactionCount ?? 0,
    replies: t.replies.length,
  }));
}

console.log(await commentThreads('brazil-presidential-election', 10));

The function picks the series when there is one, maps each outcome token to its market and outcome, then groups replies under their parent by parentCommentID rather than trusting array order. In our run, holders showed up as lines such as "45887 Geraldo Alckmin Yes". On a series, positions in other events of the series fall back to "other market". Add holders_only=true to hear only from people with money in the event.

How do you read comments with Polymarket's SDK?

The unified TypeScript SDK wraps all three routes:

import { CommentParentEntityType, createPublicClient } from '@polymarket/client';

const client = createPublicClient();

const pages = client.listComments({
  parentEntityId: '45915',
  parentEntityType: CommentParentEntityType.Event,
  pageSize: 20,
  order: 'createdAt',
  ascending: false,
});

const page = await pages.firstPage();
for (const comment of page.items) {
  console.log(comment.id, comment.parentCommentID ?? 'top', comment.reactionCount, comment.body);
}

const thread = await client.fetchCommentsById({ id: page.items[0].id });
console.log(thread.length);

CommentParentEntityType has Event and Series. listComments also takes getPositions and holdersOnly, and listCommentsByUserAddress({ address }) covers the user route. Field names match the API. In Python, the same call is client.list_comments(parent_entity_id=..., parent_entity_type="Event").

Is there a real-time Polymarket comments stream?

Not one to build on, as of October 2026. PolyBolt, the WebSocket that replaced RTDS for reference prices in September, has price channels only. When Polymarket moved prices off RTDS on 15 September, its changelog said "the comments topic stays on RTDS for now". That topic carried comment_created, comment_removed, reaction_created and reaction_removed events. Polymarket's real-time docs now say live comment and reaction streaming "is being retired without a replacement streaming channel", and SDK 0.11.0 marks its comments subscription as deprecated.

Poll instead. Request the newest page, keep the ids you have seen, and alert on the rest. Responses were cached for up to 90 seconds in our checks, so polling more often than about once a minute mostly returns the same page. For threads you follow, re-read GET /comments/{id} to pick up new replies.

How do you put comments next to live prices?

A comment reads differently next to the price it moved, or failed to move. Polymarket's market WebSocket streams prices for the tokens you subscribe to, as covered in our Polymarket WebSocket guide. The Predictefy API streams order books and trades from 15+ venues, Polymarket included, in one normalized format, so a comment feed can sit beside a live book wherever the same event trades.

Frequently Asked Questions

Does Polymarket have a comments API?

Yes. Gamma's GET /comments returns comments for an event or series, with profiles, reactions and replies, and needs no API key. GET /comments/{id} returns one thread, and GET /comments/user_address/{address} returns one user's comments.

How do I get comments for one Polymarket market?

Comments attach to the market's event, or to its series for recurring events, not to the market itself. Look up the market's event, then query /comments with parent_entity_type=Event and the event id, or Series and the series id. The live API rejects market as a parent type.

Why does the comments endpoint return an empty list?

Most often the event belongs to a series, and its comments live on the series. Read the event's series array and query parent_entity_type=Series with that id. Check commentCount on the event or series first to see how many to expect.

How do I get the replies to a Polymarket comment?

They arrive in the same list, directly after their parent, marked with parentCommentID. To read one thread on its own, call GET /comments/{id} with the parent's id or any reply's id. Threads are one level deep.

Can I stream Polymarket comments in real time?

Not reliably. A comments topic stayed on the legacy RTDS socket after prices moved to PolyBolt, but Polymarket says live comment and reaction streaming is being retired without a replacement. Poll GET /comments and re-read the threads you follow.

How do I find a commenter's wallet?

Read profile.proxyWallet from the comment, which is the address the Data API uses for positions and trades. The comment's userAddress is the base address, which is what the user comments route expects. Gamma's /public-profile accepts either address.