Build a production-aware AI agent token monitor using CoinMarketCap API to track Virtuals ecosystem momentum, Base AI token rotation, liquidity, and risk signals.
Introduction
AI agent tokens have become one of the fastest-moving narratives in crypto.
Virtuals Protocol sits at the center of that trend by enabling tokenized AI agents and agent-driven ecosystems.
But tracking this market is difficult.
AI agent tokens often move quickly, launch on DEXs, share duplicate symbols, and experience sudden liquidity spikes or collapses.
A useful monitor should not only track price.
It should detect:
- AI agent token momentum
- Base ecosystem rotation
- volume spikes
- DEX liquidity quality
- risky contracts
- trending narratives
- watchlist candidates
CoinMarketCap API provides the off-chain data layer required to build this system.
- CoinMarketCap Core API tracks listed AI tokens and categories
- CoinMarketCap DEX API tracks Base AI-agent pairs
- your system creates a ranked watchlist of AI agent opportunities
This guide is educational and production-aware. It is not financial advice.
Why Use CoinMarketCap API for Virtuals Monitoring?
AI agent tokens are noisy.
A strong monitor needs:
- reliable asset mapping
- category discovery
- price and volume signals
- DEX pair discovery
- liquidity validation
- security checks
- local caching and defensive parsing
CoinMarketCap API provides:
- /v1/cryptocurrency/map
- /v3/cryptocurrency/quotes/latest
- /v3/cryptocurrency/listings/latest
- /v1/cryptocurrency/categories
- /v1/cryptocurrency/category
- /v4/dex/spot-pairs/latest
- /v4/dex/pairs/quotes/latest
- /v1/dex/security/detail
This lets your tracker move from:
“AI token price went up”
toward:
“capital is rotating into liquid AI agent tokens with acceptable risk filters”
System Architecture
CoinMarketCap API
├─ Cryptocurrency Map
├─ AI / Base Categories
├─ Listings Latest
├─ Quotes Latest
├─ DEX Spot Pairs
├─ Pair Quotes
└─ Security Detail
↓
AI Agent Monitor
↓
Momentum + Liquidity + Risk Score
↓
Watchlist / Alerts / Dashboard
Important Architecture Clarification
It is not:
- an execution engine
- an on-chain oracle
- a microsecond trading feed
For any automated trading system, your bot must validate final pool state, contract state, and execution conditions on-chain before submitting transactions.
CoinMarketCap helps you decide what deserves attention.
Execution belongs to your wallet, router, smart contract, or trading infrastructure.
Project Setup
import os
import time
import requests
import pandas as pd
import numpy as np
CMC_API_KEY = os.getenv("CMC_API_KEY")
CMC_API_KEY = os.getenv("CMC_API_KEY")
CMC_BASE_URL = "https://pro-api.coinmarketcap.com"
HEADERS = {
"Accept": "application/json",
"Content-Type": "application/json",
"X-CMC_PRO_API_KEY": CMC_API_KEY,
}
Step 1: Map Virtuals and AI Agent Tokens
Never use symbols as unique identifiers.
AI agent ecosystems often contain duplicate or similar symbols.
Use CoinMarketCap IDs from:
/v1/cryptocurrency/map
Example
def map_assets(symbols="VIRTUAL"):
url = f"{CMC_BASE_URL}/v1/cryptocurrency/map"
params = {
"symbol": symbols
}
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=20
)
r.raise_for_status()
return r.json()["data"]
The response may include a platform object with token contract data.
Use the numeric CoinMarketCap id for Core API requests.
Use contract_address + network_slug for DEX-only tokens.
Step 2: Discover AI and Base Categories
Use categories to discover AI, AI & Big Data, Base Ecosystem, and related narratives dynamically.
Endpoint:
/v1/cryptocurrency/categories
Do not hardcode category IDs. Fetch them dynamically.
Example
def fetch_categories():
url = f"{CMC_BASE_URL}/v1/cryptocurrency/categories"
r = requests.get(
url,
headers=HEADERS,
timeout=30
)
r.raise_for_status()
return r.json()["data"]
Find AI / Base Categories
def find_ai_categories(categories):
keywords = [
"ai",
"artificial intelligence",
"big data",
"base ecosystem",
"agent",
]
matches = []
for category in categories:
searchable = " ".join([
str(category.get("name", "")),
str(category.get("title", "")),
str(category.get("description", "")),
]).lower(
if any(k in searchable for k in keywords):
matches.append({
"id": category.get("id"),
"name": category.get("name"),
"title": category.get("title"),
"num_tokens": category.get("num_tokens"),
"market_cap": category.get("market_cap"),
"volume": category.get("volume"),
"avg_price_change": category.get("avg_price_change"),
"market_cap_change": category.get("market_cap_change"),
})
return pd.DataFrame(matches)
Step 3: Fetch Tokens From a Category
Once you identify the AI or Base category ID, fetch the tokens inside it.
Endpoint:
/v1/cryptocurrency/category
This endpoint returns category-level metrics and the assets inside the category.
Useful category fields include:
- market_cap
- volume
- avg_price_change
- num_tokens
- market_cap_change
Example
def fetch_category(category_id):
url = f"{CMC_BASE_URL}/v1/cryptocurrency/category"
params = {
"id": category_id
}
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=30
)
r.raise_for_status()
return r.json()["data"]
Step 4: Fetch Core Quotes
For already listed AI tokens, use:
/v3/cryptocurrency/quotes/latest
Example
def fetch_quotes(ids):
url = f"{CMC_BASE_URL}/v3/cryptocurrency/quotes/latest"
params = {
"id": ids
}
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=20
)
r.raise_for_status()
return r.json()["data"]
Step 5: Parse Core API Quotes Correctly
In the live Core API v3 response, quote is returned as a list of quote objects.
For USD, select the object where:
symbol == "USD"
Do not parse it as a dictionary keyed by USD.
Incorrect:
usd = asset.get("quote", {}).get("USD", {})
Correct:
quotes = asset.get("quote", [])
usd = next((q for q in quotes if q.get("symbol") == "USD"), {})
Normalize Core Asset
def get_core_usd_quote(asset):
quotes = asset.get("quote", [])
return next(
(q for q in quotes if q.get("symbol") == "USD"),
{}
)
def normalize_core_asset(asset):
usd = get_core_usd_quote(asset)
return {
"id": asset.get("id"),
"symbol": asset.get("symbol"),
"name": asset.get("name"),
"price": usd.get("price"),
"volume_24h": usd.get("volume_24h") or 0,
"market_cap": usd.get("market_cap") or 0,
"fully_diluted_market_cap": usd.get("fully_diluted_market_cap") or 0,
"percent_change_1h": usd.get("percent_change_1h") or 0,
"percent_change_24h": usd.get("percent_change_24h") or 0,
"percent_change_7d": usd.get("percent_change_7d") or 0,
"last_updated": asset.get("last_updated"),
"tags": asset.get("tags", []),
}
Useful fields inside the USD quote include:
- price
- volume_24h
- market_cap
- fully_diluted_market_cap
- percent_change_1h
- percent_change_24h
- percent_change_7d
Fields like tvl and tvl_ratio usually return null for AI agent tokens and should not be used as required inputs.
Step 6: Use Listings for Basic-Friendly AI Discovery
Paid trending endpoints are useful, but Basic users need a fallback.
Use:
/v3/cryptocurrency/listings/latest
with volume and momentum filters.
Example
def fetch_ai_candidates(limit=500):
url = f"{CMC_BASE_URL}/v3/cryptocurrency/listings/latest"
params = {
"limit": limit,
"sort": "volume_24h",
"volume_24h_min": 1_000_000,
"percent_change_24h_min": 5,
"aux": "tags"
}
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=30
)
r.raise_for_status()
return r.json()["data"]
Then filter locally using tags for AI-related labels.
Step 7: Discover AI Agent Pairs on Base
Many AI agent tokens gain early liquidity on Base DEXs.
Use:
/v4/dex/spot-pairs/latest
For reliable requests, include both:
- network_slug=base
- dex_slug=<valid_dex_slug>
Confirm valid DEX slugs before publishing or deploying. In practice, use a known working Base DEX slug from your validation environment, such as baseswap, and treat DEX registry paths as unstable if they return server errors during testing.
Example
def fetch_base_ai_pairs(limit=100, dex_slug="baseswap"):
url = f"{CMC_BASE_URL}/v4/dex/spot-pairs/latest"
params = {
"network_slug": "base",
"dex_slug": dex_slug,
"sort": "volume_24h",
"limit": limit,
}
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=30
)
r.raise_for_status()
return r.json()["data"]
Important:
Some visible DEX names may not match the exact CoinMarketCap registry slug. Always confirm slugs before deploying.
Step 8: Parse DEX v4 Quotes Correctly
DEX v4 responses use quote as a list.
For USD, select the item where:
convert_id == "2781"
Do not parse DEX v4 like Core API.
DEX USD Helper
def get_dex_usd_quote(item):
quotes = item.get("quote", [])
return next(
(q for q in quotes if str(q.get("convert_id")) == "2781"),
{}
)
Normalize DEX Pair
def normalize_dex_pair(pair):
usd = get_dex_usd_quote(pair)
return {
"pair_address": pair.get("contract_address"),
"network_slug": pair.get("network_slug"),
"dex_slug": pair.get("dex_slug"),
"base_asset_contract_address": pair.get("base_asset_contract_address"),
"quote_asset_contract_address": pair.get("quote_asset_contract_address"),
"base_asset_ucid": pair.get("base_asset_ucid"),
"quote_asset_ucid": pair.get("quote_asset_ucid"),
"price": usd.get("price"),
"liquidity": usd.get("liquidity") or 0,
"volume_24h": usd.get("volume_24h") or 0,
"fully_diluted_value": usd.get("fully_diluted_value") or 0,
"percent_change_price_24h": usd.get("percent_change_price_24h") or 0,
}
In DEX v4, use fully_diluted_value rather than market_cap.
Step 9: Fetch Pair Quotes for Liquidity Detail
Use:
/v4/dex/pairs/quotes/latest
for detailed pair-level data.
Example
def fetch_pair_quote(pair_address, network_slug="base"):
url = f"{CMC_BASE_URL}/v4/dex/pairs/quotes/latest"
params = {
"contract_address": pair_address,
"network_slug": network_slug,
"aux": ",".join([
"pool_base_asset",
"pool_quote_asset",
"percent_pooled_base_asset",
"buy_tax",
"sell_tax",
"security_scan",
])
}
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=30
)
r.raise_for_status()
return r.json()["data"]
Useful fields include:
- price
- liquidity
- volume_24h
- fully_diluted_value
- pool_base_asset
- pool_quote_asset
- buy_tax
- sell_tax
- security_scan
Step 10: Apply Security Filters
Base is EVM-compatible, so use:
/v1/dex/security/detail
Parameters:
- platformName=base
- address=<token_contract>
Example
def fetch_security(token_address):
url = f"{CMC_BASE_URL}/v1/dex/security/detail"
params = {
"platformName": "base",
"address": token_address,
}
try:
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=20
)
r.raise_for_status()
return r.json()["data"]
except requests.RequestException:
return None
Useful fields include:
- honeypot
- transfer_pausable
- blacklisted
- buyTax
- sellTax
Security caveat:
Security scans come from third-party providers such as Go+.
CoinMarketCap does not verify the accuracy or timeliness of these third-party results.
Use them as filters, not guarantees.
Step 11: Build an AI Agent Momentum Score
Combine:
- volume
- momentum
- liquidity
- FDV
- security result
Example
def ai_agent_score(token):
volume = token.get("volume_24h") or 0
momentum = token.get("percent_change_24h") or token.get("percent_change_price_24h") or 0
liquidity = token.get("liquidity") or 0
fdv = token.get("fully_diluted_market_cap") or token.get("fully_diluted_value") or 0
volume_score = min(volume / 1_000_000, 1)
momentum_score = max(min(momentum / 50, 1), -1)
liquidity_score = min(liquidity / 100_000, 1)
fdv_penalty = 0
if fdv > 100_000_000 and liquidity < 100_000:
fdv_penalty = 0.25
return (
volume_score * 0.35 +
momentum_score * 0.30 +
liquidity_score * 0.35 -
fdv_penalty
)
This favors tokens with real liquidity and volume instead of only price movement.
Step 12: Paid Trending and Community Endpoints
These endpoints are useful for attention monitoring but require paid plans:
/v1/cryptocurrency/trending/latest
/v1/community/trending/token
/v1/community/trending/topic
Plan warning:
- trending/latest requires Startup or higher
- community trending endpoints require Standard, Professional, or Enterprise
- Basic plans return HTTP 403 Error 1006: Plan Not Authorized
Basic-friendly fallback:
- use /v3/cryptocurrency/listings/latest
- sort by volume_24h
- filter by percent_change_24h
- filter locally using AI-related tags
- use /v4/dex/spot-pairs/latest for Base DEX momentum
Step 13: Historical Momentum
Use:
/v3/cryptocurrency/quotes/historical
for Core assets.
Useful intervals for AI token momentum:
- 15m for fast rotation
- 30m for cleaner momentum
- 1h for trend validation
- daily for longer-term context
Important:
- historical cache updates roughly every 5 minutes
- historical data costs 1 credit per 100 data points
- deep history may be restricted by plan tier
- Basic access may be too shallow for long backtests
For DEX pairs, use:
/v4/dex/pairs/ohlcv/historical
for short-interval on-chain pair data when available.
Step 14: Minimal End-to-End Flow
def run_virtuals_monitor():
core_assets = fetch_ai_candidates(limit=200)
normalized_core = [
normalize_core_asset(asset)
for asset in core_assets
]
base_pairs = fetch_base_ai_pairs(limit=100)
normalized_dex = [
normalize_dex_pair(pair)
for pair in base_pairs
]
combined = pd.DataFrame(normalized_core + normalized_dex)
# Prevent NaN values from breaking fallback logic in scoring.
combined.fillna(0, inplace=True)
combined["score"] = combined.apply(
lambda row: ai_agent_score(row.to_dict()),
axis=1
)
return combined.sort_values(
"score",
ascending=False
).head(20)
Rate Limits and Polling
Recommended cadence:
- quotes/latest → every 60 seconds
- listings/latest → every 60 seconds
- DEX pair discovery → every 60 seconds
- DEX pair quotes → every 60 seconds
- macro indicators → every 15 minutes
- historical → bootstrap/backtesting only
Use local caching.
Use exponential backoff for HTTP 429.
def request_with_backoff(url, params=None):
failures = 0
while True:
try:
r = requests.get(
url,
headers=HEADERS,
params=params,
timeout=30
)
r.raise_for_status()
return r.json()
except requests.HTTPError as e:
if e.response is not None and e.response.status_code == 429:
failures += 1
time.sleep(min(60 * (2 ** failures), 900))
continue
raise
Common Mistakes
Using Symbol as ID
AI agent tokens often have duplicate symbols.
Use CoinMarketCap IDs for Core API and contract_address + network_slug for DEX API.
Mixing Core and DEX quote Parsing
Core v3 uses:
quotes = asset.get("quote", [])
usd = next((q for q in quotes if q.get("symbol") == "USD"), {})
DEX v4 uses:
quote with convert_id == "2781"
Do not mix them.
Ignoring DEX Slug Requirements
For Base DEX discovery, include a valid dex_slug.
In validation, uniswap-v3 may return zero Base pairs, while baseswap can be a safer example slug. Confirm the exact working slug before deployment.
Trusting Security Flags Blindly
Security data can lag or return false positives/negatives.
Validate critical contracts on-chain.
Treating CMC as Execution Layer
CoinMarketCap identifies opportunities.
Execution must be handled separately.
Final Thoughts
Virtuals and AI agent tokens are fast-moving markets.
A useful monitor must combine:
- category discovery
- Base DEX activity
- price momentum
- volume rotation
- liquidity filters
- security checks
CoinMarketCap API provides the structured data layer for that workflow.
The result is a cleaner AI agent watchlist that avoids chasing every noisy launch.
Next Steps
To improve the monitor:
- add Discord or Telegram alerts
- store watchlist snapshots
- monitor Base DEX slugs dynamically
- add wallet-level tracking
- include community trending endpoints on paid plans
- verify contract state on-chain before execution
Better narrative tracking leads to better AI agent market intelligence.
