# Polymarket order-book snapshots and recent trades (`omraydev/polymarket-orderbook-snapshot`) Actor

Export full public Polymarket order books and recent market trades for chosen markets or token ids, once or repeated on a timed schedule.

- **URL**: https://apify.com/omraydev/polymarket-orderbook-snapshot.md
- **Developed by:** [Om Ray](https://apify.com/omraydev) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 orderbook snapshots

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Polymarket order books and recent trades

When you review a trading idea, you need to know which prices and sizes were available at the time. This actor saves every bid and ask returned by Polymarket's public order-book API, together with recent public trades for the selected tokens. You can capture one snapshot or repeat the collection at a fixed interval to keep a record of how liquidity changes.

Choose a market to include both outcome tokens, or supply token IDs when you want particular books. The actor reads public data without a Polymarket login, wallet key or API key, and it never places orders. A snapshot shows what the API returned, which doesn't tell you whether an order would have filled. Past performance is not a recommendation to trade.

### Run the actor

The `markets` input accepts market slugs and 66-character condition IDs beginning with `0x`. Event slugs and URLs won't work, and `tokenIds` takes decimal strings so JavaScript doesn't round large IDs. The example below selects the October 2026 Fed-rate market for repeated snapshots. If that market has closed, choose an active market because a closed market may have no live book and return `unavailable`.

```json
{
  "markets": ["will-there-be-no-change-in-fed-interest-rates-after-the-october-2026-meeting-20260617190324031"],
  "tokenIds": [],
  "intervalSeconds": 10,
  "durationMinutes": 1,
  "maxSnapshots": 6,
  "recentTradesLimit": 100
}
```

For a local run, install the repository dependencies with `npm ci` at the root and use the commands below. The default dataset holds one row per token for each snapshot round. The actor writes the run summary to `storage/key_value_stores/default/OUTPUT.json`, and [examples/sample-output.json](examples/sample-output.json) contains a recorded two-token capture.

```sh
cd actors/polymarket-orderbook-snapshot
npx apify run --input-file examples/input.json
```

### Read a snapshot

Every row keeps the full CLOB book response, including all returned price levels, the original numeric strings, the book timestamp and its hash. It also calculates `bestBid`, `bestAsk` and `spread` across those levels, then attaches recent market trades filtered to that token without dropping their original fields. The row identifies the token and any known market, records the cycle with UTC request and capture times, and includes errors so an unavailable book can't be mistaken for a valid empty book.

The excerpt below shows the shape of a result with a bid at $0.45 and an ask at $0.55. Those numbers are made up, and the checked-in sample has real values with every returned level. Read each row's `status` and `errors` before using its prices or trades.

```json
{
  "cycle": 0,
  "status": "ok",
  "bestBid": 0.45,
  "bestAsk": 0.55,
  "spread": 0.10000000000000003,
  "book": {
    "bids": [{ "price": "0.45", "size": "10" }],
    "asks": [{ "price": "0.55", "size": "8" }]
  },
  "errors": []
}
```

### Timing and coverage

Set `durationMinutes` to zero for a single round, or use a positive duration to schedule rounds start-to-start every `intervalSeconds`. Intervals can be between 5 and 60 seconds, with a maximum duration of 60 minutes and up to 1,000 rounds per run. Inputs must resolve to no more than 100 tokens, each of which can produce a row in every round. Slow requests can delay the schedule, and a round already underway may finish after the duration ends. The actor reads tokens one after another, so a round isn't a single instant view of the market.

The `recentTradesLimit` input requests between 0 and 500 market rows per round. The actor fetches those trades once per condition, then filters them by token, so a token can have fewer trades than the requested limit. Repeated snapshots can overlap, and `takerOnly=false` means the public response may include both participants in a trade. Treat it as a sample of recent trades rather than a complete or deduplicated history. It doesn't page back through the wallet feed, so that feed's 10,000-offset cap doesn't come into it.

For a token ID supplied alone, the actor learns its condition ID from the book. If that book is unavailable, it can't discover the token's trades and records the reason, while a known market can still return trades without an available book. HTTP requests use a browser User-Agent and make up to three attempts when an error is retryable, without retaining Cloudflare cookies. Public books and trades can change between any two requests.

### Charges and verification

You pay one `orderbook-snapshot` event for each token row that has a valid book. If the recent-trade request fails, the row is marked `partial` and still charged, while a row without a book costs nothing. A run stops when the SDK reports that you've hit the event-charge limit. The repository's `PUBLISH.md` documents pricing and Console setup.

Run `npm test` from the repository root to check token lookup, full-book preservation and both-outcome collection against controlled API responses. The tests also exercise failed or unrelated responses, repeated snapshot timing and billing limits. Collection uses Gamma's market lookup, the CLOB market and book endpoints, and the public Data API trades endpoint. It doesn't infer fills or simulate market-making returns.

# Actor input Schema

## `markets` (type: `array`):

Market slugs or 0x condition IDs. Each market expands to its outcome tokens. Event URLs are not market slugs.

## `tokenIds` (type: `array`):

Decimal token IDs as strings. At least one market or token is required. Up to 100 tokens after market expansion.

## `intervalSeconds` (type: `integer`):

Schedule start-to-start between rounds, from 5 to 60 seconds. Slow API responses delay subsequent rounds.

## `durationMinutes` (type: `number`):

Zero takes one snapshot per token. Positive values repeat until this duration elapses, with at least one round.

## `maxSnapshots` (type: `integer`):

Hard limit on rounds, not output rows. Each round emits one row per token. Recording also stops at duration or the Apify event-charge budget.

## `recentTradesLimit` (type: `integer`):

Latest public trades to fetch per market per round, then filter by token. Zero disables trade requests. Repeated snapshots overlap.

## Actor input object example

```json
{
  "markets": [
    "will-there-be-no-change-in-fed-interest-rates-after-the-october-2026-meeting-20260617190324031"
  ],
  "tokenIds": [],
  "intervalSeconds": 10,
  "durationMinutes": 0,
  "maxSnapshots": 1000,
  "recentTradesLimit": 100
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "markets": [
        "will-there-be-no-change-in-fed-interest-rates-after-the-october-2026-meeting-20260617190324031"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("omraydev/polymarket-orderbook-snapshot").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "markets": ["will-there-be-no-change-in-fed-interest-rates-after-the-october-2026-meeting-20260617190324031"] }

# Run the Actor and wait for it to finish
run = client.actor("omraydev/polymarket-orderbook-snapshot").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "markets": [
    "will-there-be-no-change-in-fed-interest-rates-after-the-october-2026-meeting-20260617190324031"
  ]
}' |
apify call omraydev/polymarket-orderbook-snapshot --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,omraydev/polymarket-orderbook-snapshot"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/QHjsNvgek1ACBdLQr/builds/O6tlii8hR7gA6IHQb/openapi.json
