Switch language for all examples
Authentication
All API requests require an API token. Generate one from your dashboard. Pass it as a Bearer token in the Authorization header.
Authorization: Bearer shadow_your_token_hereRate limits
The API is rate limited to 100 requests per minute per token on a 60-second sliding window. Exceeding this returns a 429 with a Retry-After header. Every response includes rate limit headers.
Response headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1744920060Wallets
/tradersList tracked wallets
Example
curl "https://api.polyshadow.net/traders" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"wallets": [
{
"id": "uuid",
"userId": "cognito-sub",
"address": "0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6",
"label": null,
"username": "polytrader",
"profileImage": null,
"createdAt": "2026-04-01T00:00:00Z"
}
]
}/tradersAdd a wallet to track
Accepts a wallet address (0x…) or a Polymarket username. The address is resolved to the canonical base address used by the Polymarket Data API.
Request body (JSON)
| Name | Type | Required | Description |
|---|---|---|---|
| address | string | yes | Wallet address (0x…) or Polymarket username |
| label | string | no | Optional human-readable label |
Example
curl -X POST "https://api.polyshadow.net/traders" \
-H "Authorization: Bearer shadow_your_token_here" \
-H "Content-Type: application/json" \
-d '{"address": "0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6", "label": "My trader"}'Response
{
"wallet": {
"id": "uuid",
"userId": "cognito-sub",
"address": "0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6",
"label": "My trader",
"username": "polytrader",
"profileImage": null,
"createdAt": "2026-04-01T00:00:00Z"
}
}/traders/{address}Remove a tracked wallet
Path / query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| address | string | yes | Wallet address to stop tracking |
Example
curl -X DELETE "https://api.polyshadow.net/traders/0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"success": true
}Trades
/tradesGet trade history
Returns paginated trade events for a wallet you track, grouped by market. Paginate by passing the cursor from one response into the next request.
Path / query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| address | string | yes | Wallet address to query |
| from | ISO 8601 | no | Start of date range. Defaults to epoch. |
| to | ISO 8601 | no | End of date range. Defaults to now. |
| limit | integer | no | Markets per page (1–100, default 20) |
| cursor | string | no | Pagination cursor from a previous response |
Example
curl "https://api.polyshadow.net/trades?address=0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6&from=2026-04-01T00:00:00Z&to=2026-04-15T23:59:59Z&limit=20" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"trades": [
{
"id": "trade-id",
"walletAddress": "0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6",
"marketId": "market-id",
"marketSlug": "will-btc-hit-100k",
"marketName": "Will BTC hit $100k in 2026?",
"marketCategory": "Crypto",
"outcome": "Yes",
"side": "BUY",
"size": 250,
"price": 0.72,
"usdcValue": 180,
"timestamp": "2026-04-10T14:23:00Z",
"transactionHash": "0xabc…"
}
],
"marketStatuses": [
{
"marketId": "market-id",
"closed": false,
"winningOutcome": null
}
],
"cursor": "2026-04-10T14:23:00Z",
"hasMore": true
}WebSocket
Subscribe to live trade events for your tracked wallets. Pass your API token as the token query parameter. The server automatically subscribes you to all your tracked wallets and sends a connected message — no further setup needed.
Connection URL
wss://api.polyshadow.net/ws?token=shadow_your_token_hereMessage protocol
| Dir | type | Description |
|---|---|---|
| send | ping | Keepalive — server replies with pong |
| receive | connected | Sent on connect — includes {"wallets":["0x…"]} with all your tracked wallet addresses |
| receive | trade | New trade event — includes {"data":{…TradeEvent}}. data.walletAddress identifies which wallet triggered it |
| receive | pong | Keepalive response |
| receive | error | Error — includes {"message":"…"} |
Keepalive
The server sends a ping every 30 seconds. Your client must reply with a pong — if no response is received before the next ping, the server closes the connection. Your client can also send its own pings at any time and the server will reply with pong. If disconnected, reconnect with the same token and the server will re-subscribe you automatically.
// server sends every 30s:
{ "type": "ping" }
// client must reply:
{ "type": "pong" }Trade event response
{
"type": "trade",
"data": {
"id": "0xf88e635f5bc4b3e33ed2b7613c1b652b43e891c44141c891d6ff12a3b8b096c8::40296644920834000343830446318628686223790341239140458977849244903283438059262::BUY",
"walletAddress": "0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6",
"walletUsername": "polytrader",
"marketId": "0x1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a",
"marketSlug": "will-btc-hit-100k-2026",
"marketName": "Will BTC hit $100k in 2026?",
"marketCategory": "Crypto",
"outcome": "Yes",
"side": "BUY",
"size": 250,
"price": 0.72,
"usdcValue": 180,
"timestamp": "2026-04-15T14:23:00.000Z",
"transactionHash": "0xf88e635f5bc4b3e33ed2b7613c1b652b43e891c44141c891d6ff12a3b8b096c8",
"marketClosed": false,
"winningOutcome": null,
"marketIcon": "https://polymarket.com/images/markets/will-btc-hit-100k.png",
"marketEndDate": "2026-12-31T23:59:59.000Z",
"marketPrices": [
{
"outcome": "Yes",
"price": 0.72
},
{
"outcome": "No",
"price": 0.28
}
],
"marketTokenIds": [
{
"outcome": "Yes",
"tokenId": "40296644920834000343830446318628686223790341239140458977849244903283438059262"
},
{
"outcome": "No",
"tokenId": "71703355079165999656169553681371313776209658760859541022150755096716561940737"
}
]
}
}id format is txHash::tokenId::side. The enrichment fields (marketClosed, winningOutcome, marketIcon, marketEndDate, marketPrices, marketTokenIds) are present when available and may be omitted if enrichment data could not be fetched.
Telegram notifications
Receive a Telegram message for every trade on your tracked wallets. Available on Pro and Max plans. Connect your account from the notifications settings page.
How it works
- 1Go to Notifications in your dashboard and click Connect Telegram.
- 2Your browser opens a deep-link to the Shadow bot in Telegram.
- 3Tap Start in Telegram — the bot confirms your account is connected.
- 4Every trade on your tracked wallets is sent as a Telegram message in real time.
Message format
Shadow Trade Alert
Will BTC hit $100k in 2026?
BUY Yes
250 shares @ 72.0c
Value: $180.00 USDC
Wallet: polytrader (0xcb15...01c6)Notification API
| Method | Path | Description |
|---|---|---|
| GET | /me/notifications | Get current notification preferences |
| PATCH | /me/notifications | Toggle Telegram on/off. Body: {"telegramEnabled": true} |
| POST | /me/notifications/telegram/connect | Generate a Telegram bot deep-link to connect your account |
| DELETE | /me/notifications/telegram | Disconnect Telegram and disable notifications |
Connect via API
# 1. Generate a Telegram bot link
curl -X POST "https://api.polyshadow.net/me/notifications/telegram/connect" \
-H "Authorization: Bearer shadow_your_token_here"
# => { "url": "https://t.me/PolyshadowBot?start=<token>" }
# 2. Open the URL — the user taps Start in Telegram
# 3. Poll until connected
curl "https://api.polyshadow.net/me/notifications" \
-H "Authorization: Bearer shadow_your_token_here"
# => { "telegramChatId": "12345678", "telegramEnabled": true }Webhook
Receive a POST request to your HTTPS endpoint for every trade on your tracked wallets. Available on Pro and Max plans. Configure your endpoint from the notifications settings page or via the API below.
Payload
Every delivery is a POST with Content-Type: application/json. Your endpoint must respond with any 2xx status within 10 seconds.
{
"event": "trade",
"timestamp": "2026-04-17T10:00:00.000Z",
"data": {
"id": "0xf88e...::40296...::BUY",
"walletAddress": "0xcb15489ebdbe6c0e48e2b2efb0f5ab23d62401c6",
"walletUsername": "polytrader",
"marketName": "Will BTC hit $100k in 2026?",
"side": "BUY",
"outcome": "Yes",
"size": 250,
"price": 0.72,
"usdcValue": 180,
"timestamp": "2026-04-17T10:00:00.000Z"
}
}Request signing
If you configure a signing secret, every request includes an X-Shadow-Signature header. Verify it to confirm the request came from Polyshadow.
X-Shadow-Signature: sha256=<hex-encoded HMAC-SHA256 of the raw request body>/me/webhookGet webhook config
Returns the current webhook configuration and the last 10 delivery attempts.
Example
curl "https://api.polyshadow.net/me/webhook" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"webhook": {
"id": "uuid",
"url": "https://your-server.com/webhook",
"enabled": true,
"hasSecret": true,
"createdAt": "2026-04-01T00:00:00Z"
},
"invocations": [
{
"id": "uuid",
"statusCode": "200",
"responseBody": "ok",
"createdAt": "2026-04-17T10:00:00Z"
},
{
"id": "uuid",
"statusCode": null,
"responseBody": "fetch failed: connection refused",
"createdAt": "2026-04-17T09:55:00Z"
}
]
}/me/webhookCreate or update webhook
Saves a webhook endpoint. The URL must use HTTPS and must not point to a private IP. Providing a secret enables HMAC-SHA256 request signing via the X-Shadow-Signature header.
Request body (JSON)
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | yes | HTTPS endpoint URL |
| secret | string | no | Signing secret — if set, requests include X-Shadow-Signature: sha256=<hex> |
Example
curl -X POST "https://api.polyshadow.net/me/webhook" \
-H "Authorization: Bearer shadow_your_token_here" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-server.com/webhook", "secret": "your-signing-secret"}'Response
{
"webhook": {
"id": "uuid",
"url": "https://your-server.com/webhook",
"enabled": true,
"hasSecret": true,
"createdAt": "2026-04-01T00:00:00Z"
}
}/me/webhookEnable or disable webhook
Request body (JSON)
| Name | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | yes | true to enable, false to disable |
Example
curl -X PATCH "https://api.polyshadow.net/me/webhook" \
-H "Authorization: Bearer shadow_your_token_here" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'Response
204 No Content/me/webhookRemove webhook
Example
curl -X DELETE "https://api.polyshadow.net/me/webhook" \
-H "Authorization: Bearer shadow_your_token_here"Response
204 No Content/me/webhook/testSend a test delivery
Fires a test payload to your webhook endpoint immediately. Useful for verifying connectivity and signature validation.
Example
curl -X POST "https://api.polyshadow.net/me/webhook/test" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"statusCode": "200",
"responseBody": "ok"
}Account
/me/subscriptionGet subscription details
Example
curl "https://api.polyshadow.net/me/subscription" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"subscription": {
"tier": "pro",
"status": "active",
"maxWallets": 4,
"historyAccess": true,
"currentPeriodEnd": "2026-05-15T00:00:00Z"
}
}/me/api-tokenGet API token metadata
Returns metadata about your current token. The token value itself is never returned after initial creation.
Example
curl "https://api.polyshadow.net/me/api-token" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"token": {
"id": "uuid",
"createdAt": "2026-04-01T00:00:00Z",
"lastUsedAt": "2026-04-15T10:30:00Z"
}
}/me/api-tokenGenerate or rotate token
Creates a new API token, immediately revoking any existing one. The plaintext token is returned exactly once — store it securely.
Example
curl -X POST "https://api.polyshadow.net/me/api-token" \
-H "Authorization: Bearer shadow_your_token_here"Response
{
"token": "shadow_a3f2c91e…"
}/me/api-tokenRevoke API token
Example
curl -X DELETE "https://api.polyshadow.net/me/api-token" \
-H "Authorization: Bearer shadow_your_token_here"Response
204 No Content