RugAlert API

A free, open API for Solana validator rug detection, commission history, stake, uptime, and decentralization metrics. No API key required. All read endpoints live under /api/v1 and return a stable JSON envelope.

Basics

  • Base URL: https://rugalert.pumpkinspool.com
  • Rate limit: 60 requests per minute per IP. Exceeding it returns 429 with a Retry-After header. Every response includes X-RateLimit-* headers.
  • Freshness: validator and event data is refreshed by a snapshot job roughly every 15 minutes; responses are CDN-cached for up to 5 minutes (30 seconds for /api/v1/epoch).
  • Networks: add ?network=testnet or ?network=alpenglow to any endpoint. Mainnet is the default.
  • Envelope: success responses are { "data": ..., "meta": ... }; errors are { "error": { "code", "message" } }.
  • Conventions: field names are camelCase, timestamps are ISO 8601, and stake amounts are provided as both exact lamports (string) and SOL (number): { "lamports": "1000000000", "sol": 1 }.
  • CORS: all endpoints allow cross-origin requests from any domain.
  • Versioning: v1 response shapes are a stable contract. New fields may be added; existing fields will not be renamed or removed without a new version.

Endpoints

GET/api/v1/validators

List validators

Paginated validator leaderboard ranked by active stake (descending). Includes commission, stake breakdown, delinquency, Jito/BAM flags, and client type.

ParameterInDescription
pagequeryPage number, 1-based. Default 1.
limitqueryResults per page, 1-100. Default 50.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators?page=1&limit=10"
{
  "data": [
    {
      "votePubkey": "DsiG71AvUHUEo9rMMHqM9NAWQ6ptguRAHyot6wGzLJjx",
      "name": "Pumpkin's Pool",
      "rank": 42,
      "commission": 5,
      "activeStake": { "lamports": "123456789000000", "sol": 123456.789 },
      "delinquent": false,
      "jitoEnabled": true,
      ...
    }
  ],
  "meta": { "page": 1, "limit": 10, "total": 1500, "totalPages": 150, ... }
}
GET/api/v1/validators/{votePubkey}

Get validator profile

Full profile for one validator: metadata, commission, stake, latest MEV snapshot, and latest performance data (skip rate, vote credits). Returns 404 if unknown.

ParameterInDescription
votePubkeyrequiredpathBase58-encoded vote account public key.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators/DsiG71AvUHUEo9rMMHqM9NAWQ6ptguRAHyot6wGzLJjx"
{
  "data": {
    "votePubkey": "DsiG71...",
    "name": "Pumpkin's Pool",
    "commission": 5,
    "activeStake": { "lamports": "...", "sol": 123456.789 },
    "mev": { "epoch": 875, "mevCommission": 8, "priorityFeeCommission": null },
    "performance": { "epoch": 875, "skipRate": 0.42, "voteCredits": 12345, ... },
    ...
  }
}
GET/api/v1/validators/{votePubkey}/events

Validator events

All commission change events for one validator (inflation and MEV), most recent first. Severity is RUG, CAUTION, or INFO; source is COMMISSION or MEV.

ParameterInDescription
votePubkeyrequiredpathBase58-encoded vote account public key.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators/{votePubkey}/events"
{
  "data": [
    {
      "severity": "RUG",
      "source": "COMMISSION",
      "fromCommission": 5,
      "toCommission": 100,
      "epoch": 874,
      "createdAt": "2026-06-30T14:15:00.000Z",
      ...
    }
  ],
  "meta": { "total": 3, "votePubkey": "..." }
}
GET/api/v1/validators/{votePubkey}/commission-history

Commission history

Per-epoch commission timeline (inflation and MEV, forward-filled) suitable for charting. A null mevCommission means MEV was disabled or never enabled.

ParameterInDescription
votePubkeyrequiredpathBase58-encoded vote account public key.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators/{votePubkey}/commission-history"
{
  "data": [
    { "epoch": 850, "commission": 5, "mevCommission": 8 },
    { "epoch": 874, "commission": 100, "mevCommission": 8 }
  ],
  "meta": { "total": 2, "votePubkey": "..." }
}
GET/api/v1/validators/{votePubkey}/stake-history

Stake history

Per-epoch active stake and network rank for one validator.

ParameterInDescription
votePubkeyrequiredpathBase58-encoded vote account public key.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators/{votePubkey}/stake-history"
{
  "data": [
    {
      "epoch": 874,
      "activeStake": { "lamports": "123456789000000", "sol": 123456.789 },
      "rank": 42
    }
  ],
  "meta": { "total": 120, "votePubkey": "..." }
}
GET/api/v1/validators/{votePubkey}/uptime

Uptime history

Daily uptime records derived from 1-minute delinquency checks, oldest first, plus overall uptime in meta.

ParameterInDescription
votePubkeyrequiredpathBase58-encoded vote account public key.
daysqueryLimit to the most recent N days. Default: all history.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators/{votePubkey}/uptime?days=30"
{
  "data": [
    { "date": "2026-07-01", "uptimeChecks": 1440, "delinquentChecks": 0, "uptimePercent": 100 }
  ],
  "meta": { "daysTracked": 30, "overallUptimePercent": 99.97, ... }
}
GET/api/v1/validators/{votePubkey}/location

Location and history

Current data center / geolocation plus up to 50 recent location changes. Returns 404 if no geo data exists for the validator.

ParameterInDescription
votePubkeyrequiredpathBase58-encoded vote account public key.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/validators/{votePubkey}/location"
{
  "data": {
    "current": { "country": "Germany", "city": "Frankfurt", "dataCenter": "Hetzner", ... },
    "changes": [
      { "dataCenter": "OVH", "city": "Warsaw", "detectedAt": "2026-05-12T08:00:00.000Z" }
    ]
  }
}
GET/api/v1/events

Recent events feed

Commission change events across all validators for recent epochs. This is the same data that powers the RugAlert home feed.

ParameterInDescription
epochsqueryNumber of recent epochs to include, 1-50. Default 10.
severityqueryFilter by severity: RUG, CAUTION, or INFO.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/events?epochs=5&severity=RUG"
{
  "data": [
    {
      "votePubkey": "...",
      "validatorName": "...",
      "severity": "RUG",
      "source": "COMMISSION",
      "fromCommission": 0,
      "toCommission": 100,
      "epoch": 875,
      "createdAt": "2026-07-02T10:00:00.000Z"
    }
  ],
  "meta": { "total": 12, "latestEpoch": 875, "epochs": 5, "severity": "RUG" }
}
GET/api/v1/epochs/{epoch}/events

Rug events for an epoch

RUG events (commission and MEV) for one epoch, deduplicated to the latest event per validator per source.

ParameterInDescription
epochrequiredpathEpoch number.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/epochs/874/events"
{
  "data": [ { "severity": "RUG", "source": "MEV", "toCommission": 100, ... } ],
  "meta": { "epoch": 874, "total": 4, "uniqueValidators": 3 }
}
GET/api/v1/stats/rugs-per-epoch

Rugs per epoch

Aggregated rug counts per epoch (unique validators, commission vs MEV breakdown) plus all-time summary stats.

ParameterInDescription
epochsqueryEpochs per page, 1-100. Default 10.
offsetqueryHow many epochs back from the latest to start. Default 0.
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/stats/rugs-per-epoch?epochs=20"
{
  "data": [
    { "epoch": 874, "uniqueValidators": 3, "commissionEvents": 2, "mevEvents": 1, ... }
  ],
  "meta": {
    "latestEpoch": 875,
    "global": { "totalRuggedValidators": 210, "repeatOffenders": 34, ... }
  }
}
GET/api/v1/stats/stake-concentration

Stake concentration

Geographic stake distribution by country, data center, city, and ASN, with Nakamoto coefficients (entities needed to reach the 33.33% superminority).

ParameterInDescription
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/stats/stake-concentration"
{
  "data": {
    "summary": { "uniqueCountries": 38, "geoCoveragePercent": 97.4, ... },
    "nakamotoCoefficients": { "byCountry": 3, "byDataCenter": 5, ... },
    "byCountry": [ { "name": "United States", "stakePercent": 28.1, ... } ],
    ...
  }
}
GET/api/v1/epoch

Current epoch

Live epoch progress from RPC. Cached for 30 seconds.

ParameterInDescription
networkqueryCluster to query: mainnet (default), testnet, or alpenglow. Invalid values return 400.
curl "https://rugalert.pumpkinspool.com/api/v1/epoch"
{
  "data": {
    "epoch": 875,
    "slotIndex": 216000,
    "slotsInEpoch": 432000,
    "absoluteSlot": 378216000,
    "progressPercent": 50
  }
}

Questions, higher rate limits, or something missing? Reach out via pumpkinspool.com. If you build something with this data, an attribution link back to RugAlert is appreciated.