Skip to main content
By the end you have a small server that posts a line to a Discord channel each time a sports or esports game market settles in the leagues you pick. Each line names the game, the market type, the winning outcome, and what one share pays. The server gets settlements two ways. It reads List settled markets every minute, which works on every plan and fills any gap after a restart. On Pro and Max, it also receives the market_settled webhook, so a settlement reaches Discord within seconds of the delivery instead of at the next read. You need an API key, a Discord channel webhook URL (channel settings, then Integrations, then Webhooks), and Node.js 20 or later. See Authentication.

1. Pick the markets

Both ways take the same two filters. Use the same values for both, so the read and the webhook send the same rows. Both default to moneyline. In golf and other field events, Polymarket labels every player market moneyline, so one tournament can settle hundreds of them. A golf event slug that starts with a year has a null league, so a league filter leaves it out.

2. The server

The server keeps one cursor and the ids it has posted in settlement-notifier.json, so a restart picks up where it stopped. A settlement’s id is its condition_id and settlement_id. The webhook and the read can return the same settlement, and the server posts it once.
settlement-notifier.ts
Run it with the secrets in the environment. Leave out OXINSIDER_WEBHOOK_SECRET to run on reads alone:
The first read starts at the current time, so the channel shows only settlements from then on. To post earlier ones once, put a since time in the past in the first query, for example new Date(Date.now() - 3_600_000).toISOString() for the last hour.

3. Test it before a live settlement

The market_settled page has an example delivery: a Premier League moneyline that settled on November 7, 2026. Sign it with your secret and post it to the server. The Discord channel should show one line, and a second post of the same body shows nothing, because that settlement was already posted.
Expect 204. A 401 means the secret differs from the one the server reads.

4. Subscribe the webhook (Pro and Max)

Expose the server on a public HTTPS URL, then create the webhook with the same filters the read uses. The response carries signing_secret once; put it in OXINSIDER_WEBHOOK_SECRET and restart the server before you verify.
Then verify the endpoint with the returned verification.token, as the Webhooks guide shows. The server answers the signed challenge with 204, and the webhook becomes active.

Limits

  • A market can settle twice: first as a resolved question without payouts, then with them. The server posts both, and the first line says the payouts are not published yet.
  • A Yes or No market names its winner Yes or No. The row carries no question, so the line links the event page, where the market’s label shows which team or player it is about.
  • The read holds back the last 2 minutes, so on reads alone a settlement reaches Discord 2 to 3 minutes after we observe it.
  • The cursor keeps the filters of the first read. To change LEAGUES or MARKET_TYPES, delete settlement-notifier.json and restart.
  • If Discord refuses a post, the read stops at that settlement and tries it again a minute later. The webhook answers 503, so 0xinsider retries the delivery on its retry schedule.
  • The webhook does not send a state we first see more than 6 hours after its market resolved. The read lists it, so the server still posts it.