Skip to content

Generate your PolyTrackers API key

API key generation is available on Pro and Elite. Pro keys are read-only; Elite keys have full read + write access.

PolyTrackers API (External + AI Agent Guide)

This is the production-facing API guide for external developers and AI agents.


Scope

This guide/spec covers the full AI agent surface:

  • Auth: /api/auth/signup, /api/auth/login, /api/auth/refresh
  • Account/Tier: /api/account, /api/account/stats, /api/account/risk-profile
  • Discovery: /api/markets, /api/leaderboard, /api/clob/price, /api/trader-lookup
  • Anomalies: /api/anomalies, /api/anomalies/{id}, /api/scan/trigger, /api/scan/run
  • Recommendations & activity: /api/recommendations, /api/bets/sync
  • API keys: /api/keys, /api/keys/generate, plus public feeds
  • Trading: /api/trades, /api/trade/execute, /api/trade/history, /api/trade/orders*
  • Alerts & webhooks: /api/alerts/preferences, /api/webhooks*
  • Whale service + ingest webhooks: wallets/roster/whale control + /api/whale/webhook*

Excluded intentionally:

  • /api/mock/* simulation helpers
  • /api/cron/* scheduled internal jobs
  • /api/admin/*, /api/stripe/*, /api/telegram/*, /api/onboarding/* and other UI/operator-only routes

Auth modes

1) User auth (session cookie or bearer)

Most user-scoped agent endpoints accept authenticated user context via:

  • Supabase session cookie (sb-* managed cookies)
  • Authorization: Bearer <supabase-jwt-access-token>

2) JWT-only bearer

POST /api/keys/generate strictly verifies Supabase JWT bearer identity.

3) Personal API key bearer

Personal API keys are prefixed ptk_ and are passed as Authorization: Bearer <personal-api-key>. They carry one or more scopes:

  • signals:read — read anomaly / whale / copy signals
  • agent:full — full read + write, including real trade execution (Elite only)

Endpoints that accept personal API keys:

EndpointRequired scope
GET /api/anomaliessignals:read
GET /api/public/whale-signalssignals:read
GET /api/public/copy-signalssignals:read
POST /api/trade/executeagent:full
GET /api/trade/historyagent:full
GET/POST/DELETE /api/trade/orders*agent:full

4) Service auth

For whale-service control endpoints:

  • x-whale-service-secret: <secret> or
  • Authorization: Bearer <WHALE_SERVICE_SHARED_SECRET>

5) Scan secret

POST /api/scan/run also accepts x-scan-secret: <SCAN_SECRET> (bypasses the tier gate; used by cron/internal automation).

6) Webhook signature auth

POST /api/whale/webhook requires:

  • x-alchemy-signature = HMAC_SHA256(raw_body, ALCHEMY_WEBHOOK_SIGNING_KEY)

Outbound deliveries from /api/webhooks* are signed with your configured secret as x-polytrackers-signature: sha256=<HMAC_SHA256(raw_body, secret)>.


Tier gating (important)

Effective tier resolution: a user on free with an active trial (trial_ends_at > now) is treated as pro. Tier failures return TIER_UPGRADE_REQUIRED with the required tier and an upgradeUrl.

Free

  • GET /api/trades: mock trades only, 7-day history window.
  • GET /api/anomalies: max 5 results, 7-day retention window, with a 1-hour visibility delay (detections newer than 1 hour are hidden).
  • POST /api/scan/trigger: not allowed (403).
  • POST /api/keys/generate, GET /api/keys: not allowed (403).
  • /api/trade/*: not allowed (403).
  • /api/webhooks (create): not allowed (403).
  • /api/public/whale-signals, /api/public/copy-signals: not allowed (403).

Pro

  • GET /api/trades: mock trades only, 90-day history window (type=real rejected with 403).
  • GET /api/anomalies: max 100 results, 90-day retention window, no delay.
  • POST /api/scan/trigger: allowed, rate limited to 2/hour.
  • /api/keys + POST /api/keys/generate: allowed, but scopes are forced to signals:read only (read-only programmatic access). Limit: 1 active personal key per user.
  • /api/webhooks (create): up to 5 active webhooks.
  • /api/public/whale-signals, /api/public/copy-signals: not allowed (Elite only).
  • /api/trade/*: not allowed.

Elite

  • Full GET /api/trades access (type=real allowed); history window unlimited.
  • GET /api/anomalies: max 200 results, full retention window.
  • POST /api/scan/trigger: allowed, rate limited to 10/hour.
  • /api/keys + POST /api/keys/generate: scopes may include signals:read and/or agent:full. Limit: 1 active personal key per user.
  • /api/trade/execute, /api/trade/history, /api/trade/orders*: allowed (with agent:full scope for API-key auth).
  • /api/public/whale-signals, /api/public/copy-signals: allowed.
  • /api/webhooks (create): up to 50 active webhooks.

Rate limits

EndpointLimit
POST /api/scan/triggerPro: 2/hour, Elite: 10/hour
POST /api/keys/generate5/hour per user
POST /api/trade/execute10/minute per user
GET /api/public/whale-signals120/minute per API key
GET /api/public/copy-signals120/minute per API key

All rate-limited responses include a Retry-After header (seconds).


Quickstart (agent flow)

1) Sign up or log in

bash
curl -X POST "https://polytrackers.com/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"agent@example.com","password":"strong-password"}'

Response includes:

  • access_token
  • refresh_token
  • token_type
  • expires_in

2) Read account + tier

bash
curl "https://polytrackers.com/api/account" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Returns tier (effective tier, honoring active trial), trialEndsAt, apiKeysCount, walletsCount, onboarding + wallet-link status.

3) Discover markets

bash
curl "https://polytrackers.com/api/markets?query=btc&status=open&sort=volume&limit=25"

4) Trigger anomaly scan (Pro/Elite)

bash
curl -X POST "https://polytrackers.com/api/scan/trigger" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

5) Read anomalies

Session or personal API key (signals:read):

bash
curl "https://polytrackers.com/api/anomalies?limit=50&severity=high" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Free-tier callers see at most 5 rows, within the last 7 days, and only those detected more than 1 hour ago.

6) Read unified trade history

bash
curl "https://polytrackers.com/api/trades?type=all&status=all&sort=newest&limit=25&offset=0" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Response body includes tier and historyDepthDays (7 for free, 90 for pro, null for elite).

7) Elite-only real trade execution

Session auth:

bash
curl -X POST "https://polytrackers.com/api/trade/execute" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "conditionId":"0xconditionid",
    "side":"YES",
    "amount":20,
    "limitPrice":0.5,
    "idempotencyKey":"agent-trade-2026-04-16-001"
  }'

Personal API key with agent:full scope:

bash
curl -X POST "https://polytrackers.com/api/trade/execute" \
  -H "Authorization: Bearer $PERSONAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"conditionId":"0x...","side":"YES","amount":20,"idempotencyKey":"..."}'

API key lifecycle

Generate personal API key (JWT bearer only)

Pro callers may only request signals:read; Elite callers may additionally request agent:full. Any request is capped at 1 active personal key; revoke the existing key before generating a new one (409 API_KEY_LIMIT_REACHED).

bash
curl -X POST "https://polytrackers.com/api/keys/generate" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"nickname":"Agent Key","expiresInDays":90,"scopes":["signals:read"]}'
  • expiresInDays: 1–365, defaults to 90.
  • scopes: defaults to ["signals:read"]. Pro-tier requests for agent:full are silently downgraded to signals:read.
  • The raw api_key is returned once in the response — store it securely.

List keys

bash
curl "https://polytrackers.com/api/keys" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Use personal key for public whale feed (Elite)

bash
curl "https://polytrackers.com/api/public/whale-signals?limit=25" \
  -H "Authorization: Bearer $PERSONAL_API_KEY"

Outbound webhooks (Pro/Elite)

Create, list, delete, and test delivery endpoints live under /api/webhooks*:

  • GET /api/webhooks — list your registrations.
  • POST /api/webhooks — register a new URL with optional filters (minScore, severity[], anomalyTypes[], marketCategories[]) and a secret. Capped at 5 (Pro) / 50 (Elite); over-limit returns WEBHOOK_LIMIT_REACHED.
  • DELETE /api/webhooks/{id} — soft-delete a registration. The row is retained for audit (with deleted_at stamped and status=paused), it will stop receiving future deliveries, and historical delivery_log entries remain queryable.
  • GET /api/webhooks/{id}/deliveries — recent delivery logs.
  • POST /api/webhooks/{id}/test — fire a test payload.

Delivered payloads are signed with the registration's secret; verify x-polytrackers-signature against sha256=HMAC_SHA256(raw_body, secret).


Deletion & audit retention

PolyTrackers favors soft deletion for user-owned resources so that reporting, billing, copy-trading analytics, and security audits remain reliable. The behavior per-resource is:

ResourceEndpoint(s)Behavior
Personal API keysDELETE /api/keys?id=…Soft-revoke: is_active=false, revoked_at=now(). Authentication is rejected immediately; row is retained for audit.
Mock walletsDELETE /api/wallets, DELETE /api/mock/wallet/{id}Soft-delete: is_active=false, deleted_at=now(). Whale assignments are detached (active=false, removed_at=now()). mock_trades, whale_activity, and whale_decision_traces are preserved. Wallet names can be reused.
Mock trades (single)DELETE /api/mock/delete-trade?tradeId=…Only open trades may be deleted. Attempts to delete resolved/closed trades return 422 CANNOT_DELETE_RESOLVED_TRADE.
Mock trades (bulk)DELETE /api/mock/delete-trade (body { type })type: "open" or type: "all" bulk deletes only the open trades for the wallet. type: "closed" is rejected with 422 CANNOT_DELETE_RESOLVED_TRADE.
Outbound webhook registrationsDELETE /api/webhooks/{id}Soft-delete: deleted_at=now(), status=paused. No future deliveries fire; historical delivery_log remains queryable via GET /api/webhooks/{id}/deliveries.
Alert preferencesDELETE /api/alerts/preferencesHard reset of the preferences row.
Roster (whale) assignmentsDELETE /api/roster/{walletId}Detach: row retained, active=false, removed_at=now().
Trade ordersDELETE /api/trade/orders/{id}Cancels the live order at the CLOB; hard-removes the queued row.

Closed/resolved mock trades are never user-deletable by design — they feed the leaderboard, copy-trading scoring, and tier-history analytics, so the API returns 422 CANNOT_DELETE_RESOLVED_TRADE and the database RPCs (delete_mock_trade_atomic, bulk_delete_mock_trades_atomic) raise cannot_delete_resolved_trade (SQLSTATE P0101) as a defense in depth.


Whale service + inbound webhooks

Existing whale-service endpoints remain supported and documented in OpenAPI:

  • Wallet/roster management (/api/wallets, /api/roster*)
  • Service status/config/control (/api/whale/*)
  • Webhook ingest/events/replay (/api/whale/webhook*)

For replay automation, use dryRun: true first, then replay live once validated.


Reliability notes

  • Handle 429 on all rate-limited endpoints and respect Retry-After.
  • Treat trade execution as idempotent when you provide idempotencyKey (idempotent replays return 200 with idempotencyReused: true).
  • POST /api/keys/generate returns the raw key once — store it securely. Only one active personal key per user.
  • /api/anomalies/{id} may return 404 when a record falls outside your tier window.
  • TIER_UPGRADE_REQUIRED responses include requiredTier, currentTier, and upgradeUrl — surface these to the user/agent verbatim.