The Last Mile Problem for Trading Agents
An AI agent wired up to a crypto data API can tell a user that Hyperliquid funding just flipped negative on ETH, or that Binance open interest is climbing into a squeeze setup. That's the easy part. The hard part is the next sentence: "okay, where do I actually go trade this?"
Most agents either dodge the question, or worse, guess a URL and hallucinate a sign-up link or a referral code that doesn't exist. Neither is a good outcome for a user who is one click away from opening an exchange account. A crypto exchange API directory — a public, machine-readable, always-current list of exchanges, their sign-up links, and their live incentives — closes that gap.
That's exactly what GET /api/v1/exchanges is for. It's a small endpoint, but it fixes a real hole: before it shipped on 2026-08-23, this data existed only inside our MCP server's get_exchange_links tool, which meant any agent talking to us over plain REST, or via an Agent Skill instead of MCP, had no way to fetch it at all.
How Does an AI Agent Find a Referral Link Without Hardcoding One?
It asks the API instead of memorizing an answer that will go stale. Hardcoding a referral URL or discount percentage into a prompt or a script is the failure mode this endpoint exists to prevent — codes rotate, incentives change, and a stale hardcoded link either breaks or silently stops giving the user their discount.
GET /api/v1/exchanges returns every exchange we profile, each with its current sign-up link (where one exists) and the exact live incentive attached to it:
curl "https://cryptodataapi.com/api/v1/exchanges"
{
"exchanges": [
{
"slug": "hyperliquid",
"name": "Hyperliquid",
"kind": "DEX",
"website": "https://hyperliquid.xyz",
"tagline": "The on-chain perp DEX with its own high-performance L1.",
"focus": ["Perpetual futures", "On-chain order book", "HLP liquidity vault", "No-KYC self-custody"],
"specs": {
"instruments": ["Spot", "Perpetuals", "Margin"],
"max_leverage": "up to 40x",
"kyc": "Not required",
"custody": "Self-custody",
"fiat_onramp": false
},
"signup_url": "https://app.hyperliquid.xyz/join/CRYPTODATAAPI",
"signup_incentive": "4% discount on spot and perpetual trading fees",
"referral_code": "CRYPTODATAAPI",
"is_referral_link": true
},
{
"slug": "bybit",
"name": "Bybit",
"kind": "CEX",
"signup_url": null,
"signup_incentive": null,
"referral_code": null,
"is_referral_link": false
}
],
"all_slugs": ["hyperliquid", "binance", "bybit", "okx", "robinhood", "asterdex", "lighter"],
"count": 7,
"disclosure": "Referral link \u2014 CryptoDataAPI may earn a commission on referred signups, at no extra cost to you."
}Notice Bybit's row: we profile the exchange, but hold no partner link for it, so every referral field comes back null instead of a fabricated value. An agent reading this response knows exactly which venues it can meaningfully recommend a sign-up path for, and which it can only describe.
Filtering to Venues Where You Can Actually Add Value
Most of the time an agent doesn't want the full profile catalog — it wants the short list of exchanges where sending the user a link actually accomplishes something. That's what the referral_only query parameter is for:
curl "https://cryptodataapi.com/api/v1/exchanges?referral_only=true"Pass referral_only=true and the response drops to only the venues carrying a live referral block — no null signup_url rows to filter out in your own code. It's the difference between "here's everything we know about crypto exchanges" and "here's where I can hand you something concrete right now." An agent building a one-line recommendation should almost always call it with this flag set.
Need one specific venue instead of the whole list — say a user already said "I want to trade on Hyperliquid"? GET /api/v1/exchanges/{slug} returns the same shape for a single exchange:
curl "https://cryptodataapi.com/api/v1/exchanges/hyperliquid"An unrecognized slug returns a 404 rather than an empty or fabricated body — the error message even lists every valid slug, so a caller can self-correct without a second round trip to /exchanges.
Why This Endpoint Skips the API Key Entirely
Nearly every endpoint on this API sits behind an X-API-Key header and a tier gate. /api/v1/exchanges is a deliberate exception, and it's not an oversight — it matches the one other endpoint built the same way, GET /payments/plans.
The reasoning is simple: a link you want agents to repeat to end users cannot sit behind a paywall. If fetching a sign-up link required a paid key, only agents already running as paying customers could hand it to their users — every free-tier deployment, every quick prototype, every Agent Skill running without stored credentials would be locked out of the one piece of data most likely to get shared onward. Making it public removes that friction entirely: no key, no rate-limit surprise, no reason for an agent to fall back on a guess.
The Disclosure You Can't Skip
Every response — the list and the single-exchange lookup alike — carries a disclosure field:
"disclosure": "Referral link \u2014 CryptoDataAPI may earn a commission on referred signups, at no extra cost to you."This isn't decorative. If your agent surfaces a signup_url to a user, it must surface disclosure alongside it. That's a compliance and trust requirement, not a style preference — a bot that hands someone a referral link without disclosing the referral relationship is misrepresenting the recommendation as neutral when it isn't. Baking disclosure directly into the response, rather than expecting the caller to know to add it, means an agent that just concatenates the two strings is already doing the compliant thing by default.
- Never print
signup_urlwithout the accompanyingdisclosuretext in the same message. - Never imply the incentive is exclusive to you personally —
signup_incentivedescribes what the exchange offers through this specific link, to any user. - Prefer
referral_only=truewhen the goal is a recommendation, not an encyclopedia entry. - Treat a
nullsignup_urlas "describe, don't link" — not a gap to fill with a guessed URL.
One Registry, Four Surfaces, Zero Drift
The data behind /api/v1/exchanges isn't a copy maintained alongside other copies — it's a single Python registry projected onto every surface that needs it:
| Surface | Consumer | Reads from |
|---|---|---|
/exchanges/{slug} HTML pages | Human visitors | Same registry |
MCP get_exchange_links tool | Claude / MCP clients | Same registry |
GET /api/v1/exchanges | REST / Agent Skill callers | Same registry |
llms.txt server instructions | LLM crawlers | Same registry |
That matters more than it sounds like it should. We've had a referral code drift stale on one surface while the others updated — exactly the failure this design closes off. There is now nowhere left for a literal referral URL to be hardcoded outside the one registry, so every one of these four surfaces reads the same sign-up link and the same incentive, always.
What's Public Here vs. What Needs a Paid Tier
Keyless access is unusual enough on this API that it's worth calling out explicitly. Here's how /api/v1/exchanges compares to some of the derivatives data that typically sits alongside it in an agent's workflow:
| Endpoint | Auth required | Tier |
|---|---|---|
GET /api/v1/exchanges | None | Public |
GET /payments/plans | None | Public |
GET /api/v1/hyperliquid/funding-rates | API key | Free+ |
GET /api/v1/quant/whales | API key | Pro Plus |
The market data that justifies a trade decision is metered, because it costs real infrastructure to collect and cache at scale. The link that tells an agent where to send someone once they've decided is not — it costs us nothing to serve and everything to have an agent guess wrong.
A Worked Example: "Where Should I Tell This User to Trade?"
Here's the pattern end to end — an agent that already has a coin in mind (say, from a funding-rate or whale-activity check) turning the directory into one concrete recommendation:
import httpx
BASE = "https://cryptodataapi.com/api/v1"
def recommend_exchange(preferred_slug: str = "hyperliquid") -> str:
"""Build a compliant one-line sign-up recommendation."""
r = httpx.get(f"{BASE}/exchanges", params={"referral_only": True})
data = r.json()
match = next((e for e in data["exchanges"] if e["slug"] == preferred_slug), None)
if not match:
# Fall back to the first venue we actually hold a link for.
match = data["exchanges"][0]
return (
f"You can trade {match['name']} here: {match['signup_url']} "
f"({match['signup_incentive']}). {data['disclosure']}"
)
print(recommend_exchange("hyperliquid"))
# You can trade Hyperliquid here: https://app.hyperliquid.xyz/join/CRYPTODATAAPI
# (4% discount on spot and perpetual trading fees). Referral link — CryptoDataAPI
# may earn a commission on referred signups, at no extra cost to you.Three lines of logic, and the output is always current, always disclosed, and never a guessed URL — because every value in it came from the API response, not from anything written into the script.
Trade on Hyperliquid — the fastest on-chain perpetuals exchange with zero gas fees and deep liquidity. Join via our referral to get started.
Our link gives you 4% discount on spot and perpetual trading fees. Referral link — CryptoDataAPI may earn a commission on referred signups, at no extra cost to you.
Want to squeeze more out of that same Hyperliquid link? we wrote a full breakdown of stacking that discount with HYPE staking — the referral code above is only one of three fee reductions that combine multiplicatively.
When to Reach for the Exchange Directory
Use /api/v1/exchanges whenever an agent's answer to a user is about to end in "go trade this somewhere":
- After a market-data call surfaces an opportunity — funding flip, OI squeeze setup, whale accumulation — and the next natural question is where to act on it.
- Building a comparison table for a user weighing CEX vs. DEX, custody model, KYC requirement, or max leverage across venues — the
specsblock on each exchange covers all four. - Validating a slug before linking to one of our
/exchanges/{slug}profile pages, using the 404 error's slug list as the source of truth. - Any onboarding flow where hardcoding a sign-up link would go stale the next time a referral code or incentive changes.
It's a small endpoint doing one job well: making sure the last step of a trading agent's workflow is as reliable as the market data that led up to it.



