Polymarket & Kalshi Arbitrage Monitor avatar

Polymarket & Kalshi Arbitrage Monitor

Pricing

Pay per event

Go to Apify Store
Polymarket & Kalshi Arbitrage Monitor

Polymarket & Kalshi Arbitrage Monitor

Match public Polymarket and Kalshi binary contracts, compare outcome prices, and export confidence evidence with candidate cross-market spread calculations.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

Compare open binary contracts across Polymarket and Kalshi, inspect current outcome prices, and export explainable candidate spread calculations.

This prediction market app monitor reads the two venues' public APIs, identifies likely equivalent propositions, evaluates both YES/NO venue combinations, and saves ranked records to an Apify dataset.

It is designed for recurring prediction market arbitrage research, pricing dashboards, and analyst review—not automated trading.

What does this Actor do?

The Actor:

  1. loads open public binary contracts from Kalshi;
  2. loads open public binary contracts from Polymarket;
  3. blocks pairs with conflicting parties, offices, directions, or numeric terms;
  4. scores remaining pairs using shared terms, numeric terms, and expiry proximity;
  5. compares Kalshi YES + Polymarket NO with the reverse combination;
  6. subtracts your configurable fee and slippage estimate;
  7. ranks and exports matched contracts with source links and matching evidence.

Every result contains both source quotes. You can inspect why a pair matched instead of relying on an opaque label.

Who is this prediction market app monitor for?

  • Prediction-market analysts comparing prices across platforms.
  • Quant researchers building an observation history from scheduled runs.
  • Traders creating a shortlist for manual settlement-rule and depth checks.
  • Journalists and academics studying cross-platform pricing differences.
  • Data teams feeding matched prediction market prices into a warehouse or dashboard.
  • Automation builders feeding analytical output into their own external alert workflows.

Why use it?

Polymarket and Kalshi describe related contracts differently. A direct title join misses useful pairs, while a loose keyword join creates dangerous false matches.

This Actor combines:

  • public structured APIs rather than browser automation;
  • event and contract context from both venues;
  • conservative proposition-conflict checks;
  • an explainable confidence score;
  • displayed bid/ask, liquidity, volume, expiry, and source identity;
  • configurable topic, confidence, expiry, liquidity, fee, and spread filters;
  • stable match IDs for recurring monitoring.

It does not claim that a high score proves identical settlement rules. Manual verification remains essential.

What data can I export?

FieldMeaning
rankPosition after candidate status, net spread, and confidence sorting
matchIdStable hash of the Kalshi and Polymarket market IDs
matchedTitleHuman-readable Kalshi event and proposition
strategyLower-cost displayed YES plus NO venue combination
candidateArbitrageWhether estimated net spread meets your threshold
combinedCostDisplayed ask cost for a theoretical $1 payout
grossSpreadPercent(1 - combinedCost) × 100
estimatedFeesPercentUser-provided fee and slippage estimate
estimatedNetSpreadPercentGross spread minus estimated fees
matchConfidenceSimilarity score from 0 to 1
matchReasonsShared terms, numeric evidence, and expiry evidence
expiryDifferenceHoursDifference between displayed expiry timestamps
kalshiKalshi identity, URL, expiry, prices, liquidity, and volume
polymarketPolymarket identity, URL, expiry, prices, liquidity, and volume
observedAtUTC observation timestamp

Price, liquidity, or volume fields can be null when a source does not provide them.

How to run the monitor

  1. Open the Actor in Apify Console.
  2. Leave keywords empty for broad discovery, or add a real topic such as Alexandria Ocasio-Cortez.
  3. Choose how many contracts to scan per venue.
  4. Keep minMatchConfidence at 0.4 initially.
  5. Set a realistic combined fee and slippage estimate.
  6. Keep includeNonProfitable enabled when you need all matched price comparisons.
  7. Disable it when you only need pairs meeting minNetSpreadPercent.
  8. Click Start.
  9. Review the Matched prediction contracts dataset view.
  10. Open both source URLs and compare full settlement rules before acting.

Input parameters

keywords

Optional topic phrases. A phrase must appear in both contracts in a pair. Use it to focus a run on a state, candidate, asset, league, or macro topic.

maxItems

Maximum matched records saved to the default dataset. Allowed range: 1–1,000. Default: 25.

maxMarketsPerVenue

Maximum open binary contracts loaded from each venue. Allowed range: 100–5,000. Default: 1,500.

Higher coverage takes longer but may find more current overlap.

minMatchConfidence

Minimum lexical, numeric, and expiry confidence. Allowed range: 0.2–1. Default: 0.4.

Lower values increase recall and false-match risk. Raise the value for precision-sensitive workflows.

maxExpiryDifferenceHours

Reject pairs whose displayed expiries differ by more than this value. Default: 720 hours.

Different timestamps can still represent similar settlement periods, so always inspect the rules.

estimatedFeesPercent

Combined fee and slippage estimate subtracted from the gross spread. Default: 2%.

This is an analytical assumption, not a source-provided quote.

minNetSpreadPercent

Threshold used for candidateArbitrage and, when filtering is enabled, dataset inclusion. Default: 0%.

minLiquidityUsd

Require both source contracts to report at least this displayed liquidity. Default: 0.

A zero value preserves contracts where liquidity is omitted.

includeNonProfitable

When true, matched contracts remain useful for cross-market monitoring even if the estimated spread is below the threshold. When false, only threshold-meeting pairs are saved.

Example input

{
"keywords": ["Alexandria Ocasio-Cortez"],
"maxItems": 10,
"maxMarketsPerVenue": 5000,
"minMatchConfidence": 0.4,
"maxExpiryDifferenceHours": 720,
"estimatedFeesPercent": 2,
"minNetSpreadPercent": 0,
"includeNonProfitable": true
}

This current-data example returns matched 2028 nomination propositions while they remain open on both venues. Prediction-market inventories change, so a topic can naturally return no records later.

Example output

{
"rank": 1,
"matchId": "a761264d80a3dd2169e7",
"matchedTitle": "2028 Democratic presidential nominee: Will Alexandria Ocasio-Cortez be the Democratic Presidential nominee in 2028?",
"strategy": "Buy Kalshi YES + Polymarket NO",
"candidateArbitrage": true,
"combinedCost": 0.98,
"grossSpreadPercent": 2,
"estimatedFeesPercent": 2,
"estimatedNetSpreadPercent": 0,
"matchConfidence": 0.893,
"matchReasons": [
"7 shared terms: 2028, democratic, presidential, nominee, alexandria, ocasio, cortez",
"6 shared adjacent phrases",
"matching numeric terms: 2028",
"contract expiries differ by 15 hours"
],
"expiryDifferenceHours": 15,
"kalshi": {
"venue": "Kalshi",
"marketId": "KXPRESNOMD-28-AOC",
"url": "https://kalshi.com/markets?search=KXPRESNOMD-28-AOC",
"yesAsk": 0.18,
"noAsk": 0.83
},
"polymarket": {
"venue": "Polymarket",
"marketId": "559653",
"url": "https://polymarket.com/event/democratic-presidential-nominee-2028",
"yesAsk": 0.201,
"noAsk": 0.8
},
"observedAt": "2026-08-15T07:01:59.971Z"
}

Quotes move continuously. The example shows the record shape, not a current recommendation.

How matching confidence works

The matcher first creates candidate pairs sharing at least one indexed term. It then scores:

  • overlap relative to the shorter title;
  • Jaccard overlap across both titles;
  • matching numeric proposition terms;
  • displayed expiry proximity.

It rejects pairs with conflicting:

  • political parties;
  • political offices;
  • above/below or before/after directions;
  • increase/decrease directions;
  • numeric proposition terms.

matchReasons exposes the supporting evidence. Even a score of 0.99 is not a settlement guarantee.

How candidate spread calculations work

For each pair, the Actor compares:

Kalshi YES ask + Polymarket NO ask
Polymarket YES ask + Kalshi NO ask

It selects the cheaper displayed combination.

gross spread % = (1 - combined cost) × 100
estimated net spread % = gross spread % - estimatedFeesPercent

The calculation does not model order-book depth, partial fills, deposits, withdrawals, taxes, changing quotes, or venue-specific settlement risk.

How much does it cost to monitor Polymarket and Kalshi spreads?

The Actor uses pay-per-event pricing:

  • one start event per run;
  • one item event for each matched record actually saved;
  • no charge for rejected, duplicate, or failed candidate pairs.

The active rates are a $0.01 start plus the applicable tiered item rate. At the BRONZE item rate of $0.0016 per match, example totals are:

Saved matchesExample total
1$0.0116
10$0.026
100$0.17

Apify account tiers can apply different item rates. Always check the pricing panel for the active tier before a run. Compute usage is covered by the Actor under PPE pricing.

Scheduling recurring arbitrage monitoring

Create an Apify Schedule with a stable input. For monitoring, keep includeNonProfitable enabled so a spread history does not disappear when it crosses zero.

A useful workflow is:

  1. run every 15–60 minutes;
  2. export dataset rows to a table keyed by matchId and observedAt;
  3. compare the latest two observations;
  4. alert only after your own confidence, liquidity, rule-equivalence, and fee checks;
  5. retain source URLs for auditability.

The Actor itself does not place orders or send trading alerts.

Export to spreadsheets, databases, and BI tools

The default dataset works with:

  • CSV and Excel exports;
  • Google Sheets integrations;
  • webhooks and Make;
  • Zapier;
  • REST API clients;
  • Python notebooks;
  • JavaScript data pipelines;
  • BigQuery, Snowflake, or PostgreSQL loaders;
  • dashboard tools such as Looker Studio and Power BI.

Use matchId as a cross-run pair key. Use observedAt as the observation time. Do not use rank as a stable identifier.

Run through the Apify API with cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~polymarket-kalshi-arbitrage-monitor/runs?token=$APIFY_TOKEN&waitForFinish=300" \
-H "Content-Type: application/json" \
-d '{
"keywords": ["Alexandria Ocasio-Cortez"],
"maxItems": 10,
"maxMarketsPerVenue": 5000,
"minMatchConfidence": 0.4,
"includeNonProfitable": true
}'

Fetch dataset items from the defaultDatasetId returned by the run. Do not put tokens in committed source code.

Run with JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/polymarket-kalshi-arbitrage-monitor').call({
keywords: ['Alexandria Ocasio-Cortez'],
maxItems: 10,
maxMarketsPerVenue: 5000,
minMatchConfidence: 0.4,
includeNonProfitable: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Run with Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/polymarket-kalshi-arbitrage-monitor").call(
run_input={
"keywords": ["Alexandria Ocasio-Cortez"],
"maxItems": 10,
"maxMarketsPerVenue": 5000,
"minMatchConfidence": 0.4,
"includeNonProfitable": True,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Use with Apify MCP

Add the Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/polymarket-kalshi-arbitrage-monitor"

Claude Desktop setup

Add this server to Claude Desktop's MCP configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/polymarket-kalshi-arbitrage-monitor"
}
}
}

Cursor setup

Add the same apify HTTP server URL under Cursor Settings → MCP and enable it for the workspace.

VS Code setup

Add the same apify HTTP server URL to the VS Code MCP server configuration, then start the server from the MCP tools panel.

Example prompts:

  • “Run the Polymarket Kalshi monitor for Alexandria Ocasio-Cortez and summarize matched prices.”
  • “Scan both platforms, keep non-profitable matches, and return the five highest-confidence pairs.”
  • “Run with zero estimated fees and show positive displayed gross spreads for manual review.”

Treat model summaries as secondary analysis; preserve the source dataset and URLs.

Limits and failure behavior

  • The public source APIs can change, rate-limit, or temporarily fail.
  • The Actor retries transient failures and uses a second public Kalshi API host.
  • Deterministic source errors fail the run rather than returning fabricated or stale records.
  • Coverage is bounded to 5,000 open contracts per venue to keep runtime and pair evaluation predictable.
  • A successful run can contain zero records when no contracts meet all filters.
  • Keywords apply to both sides of a pair.
  • Non-binary and Kalshi multivariate contracts are excluded.
  • Prices are snapshots and can change before any order is placed.
  • Displayed liquidity does not guarantee executable depth at the shown price.
  • Similar wording does not guarantee identical resolution criteria.

Responsible use and legality

The Actor accesses public, unauthenticated market-data endpoints. Use the output in accordance with Apify's terms, each source's terms, and laws applicable to you.

Prediction-market access and trading rules differ by location. This Actor does not bypass login, geofencing, or access controls. It does not provide financial, legal, tax, or investment advice. It does not execute trades.

Before relying on a pair:

  1. open both source links;
  2. compare the complete settlement wording and authoritative sources;
  3. confirm contract side orientation;
  4. inspect live order-book depth;
  5. account for every fee and transfer cost;
  6. confirm your eligibility to use each venue;
  7. make your own independent decision.

Troubleshooting

Why did the run return no matches?

Current overlap may be naturally sparse. Remove keywords, increase maxMarketsPerVenue, keep includeNonProfitable enabled, or cautiously lower minMatchConfidence. Do not lower confidence merely to force a result.

Why was an apparent opportunity omitted?

The pair may have conflicting numbers, direction words, political parties, offices, expiry distance, liquidity, or confidence. It may also sit beyond the bounded open-contract window.

Why is an obvious false match present?

No automated semantic matcher is perfect. Raise minMatchConfidence, add a topic keyword, and report the two source URLs and IDs for reproducible improvement. Never trade solely from the Actor's candidate label.

Why is candidateArbitrage false?

The pair is still a useful cross-market comparison, but its estimated net spread is below minNetSpreadPercent after subtracting estimatedFeesPercent. Set includeNonProfitable to false to omit those rows.

Does this guarantee risk-free profit?

No. Settlement wording, timing, fills, depth, fees, eligibility, transfers, and price movement create material risk. The Actor outputs candidates for verification, not guarantees.

Use the source-specific Actors when you need broader raw inventory or venue fields. Use this Actor when the buyer job is matched cross-market monitoring and spread calculation.

FAQ

Are prices live?

They are public API snapshots observed during the run, not streaming quotes. Schedule repeated runs for a time series.

Can I search only one venue?

No. This product emits cross-venue matches. Use the related source-specific Actor for single-venue exports.

Can I add multiple keywords?

Yes. A contract is accepted when any configured phrase appears, but each pair must pass the same keyword scope on both venues.

Does the Actor need a proxy or account?

No. It uses public anonymous APIs and exposes no automatic paid-proxy fallback.

Does it place trades?

No. It only exports analytical records.

How should I deduplicate scheduled results?

Use matchId for the pair and observedAt for each snapshot.

Can I use the data in an agent workflow?

Yes. Use Apify MCP or the REST API, but require the agent to show both source URLs, confidence reasons, and settlement-rule caveats.

Support

For reproducible help, include:

  • the Actor run URL;
  • exact input;
  • the two source market IDs or URLs;
  • expected versus observed behavior;
  • whether the source pages and APIs were available at run time.

Do not include API tokens, credentials, or private trading information.