ET10 Exchange API
Exchange 100+ cryptos for ET10 Liquidity Stream Tokens. Built for AI agents, DCA bots, and programmatic trading.
Quick Start
# Buy ET10 — single call, get deposit address
curl -X POST https://cymetica.com/api/v1/rst/buy-et10 \
-H "X-API-Key: evt_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"recipient_address":"0xYOUR_WALLET","token_symbol":"USDC"}'
# Response: { deposit_address, intent_id, chain, instructions }
# Send USDC to deposit_address → ET10 delivered automatically to your
# registered recipient_address (Ethereum mainnet), never to the sending wallet
import requests
# Buy ET10 in one call
resp = requests.post("https://cymetica.com/api/v1/rst/buy-et10",
headers={"X-API-Key": "evt_YOUR_KEY"},
json={
"recipient_address": "0xYOUR_WALLET",
"token_symbol": "USDC"
}).json()
print(f"Send USDC to: {resp['deposit_address']}")
print(f"ET10 will be delivered to: {resp['recipient_address']}")
# Send USDC → ET10 delivered automatically to your registered
# recipient_address (Ethereum mainnet), never to the sending wallet
// Buy ET10 in one call
const resp = await fetch("https://cymetica.com/api/v1/rst/buy-et10", {
method: "POST",
headers: {
"X-API-Key": "evt_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
recipient_address: "0xYOUR_WALLET",
token_symbol: "USDC"
})
}).then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
console.log(`Send USDC to: ${resp.deposit_address}`);
// Send USDC → ET10 delivered automatically to your registered
// recipient_address (Ethereum mainnet), never to the sending wallet
Authentication
Most ET10 exchange endpoints are public (token list, quotes, deposit addresses, status checks).
For programmatic purchases, use an API Key via the X-API-Key header. This skips CSRF/Origin validation — perfect for bots, AI agents, and automated systems.
# API Key auth (recommended for bots/agents/SDKs)
curl -X POST https://cymetica.com/api/v1/rst/buy-et10 \
-H "X-API-Key: evt_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"recipient_address":"0x...","token_symbol":"ETH"}'
# /deposit-intent accepts EITHER header — X-API-Key or a Bearer JWT
curl -X POST https://cymetica.com/api/v1/rst/deposit-intent \
-H "X-API-Key: $ET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"rst_address":"0x...","token_symbol":"ETH"}'
# same endpoint, browser-session auth
curl -X POST https://cymetica.com/api/v1/rst/deposit-intent \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{"rst_address":"0x...","token_symbol":"ETH"}'
Get your API key from /account → API Keys.
Buy ET10 — Single Call
The fastest way to buy ET10 programmatically. One call, no bot-registration step required — you do not have to register a bot or an app to use it. Authentication is optional but changes the limits: send your API key in X-API-Key for programmatic access (higher rate limit, no CSRF/Origin check), or call it from a browser with a CSRF token (lower per-IP rate limit).
Returns a deposit address. Send crypto to it and ET10 tokens are delivered to your wallet automatically. Deposits are auto-processed; unusually large deposits may be held briefly for review (status awaiting_approval).
Request Body
Response
curl -X POST https://cymetica.com/api/v1/rst/buy-et10 \
-H "X-API-Key: evt_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipient_address": "0xYourWalletAddress",
"token_symbol": "USDC"
}'
import requests
resp = requests.post(
"https://cymetica.com/api/v1/rst/buy-et10",
headers={"X-API-Key": "evt_YOUR_KEY"},
json={
"recipient_address": "0xYourWalletAddress",
"token_symbol": "USDC"
}
).json()
print(f"Send USDC to: {resp['deposit_address']}")
print(f"Chain: {resp['chain']} (ID: {resp['chain_id']})")
print(resp["instructions"])
const resp = await fetch("https://cymetica.com/api/v1/rst/buy-et10", {
method: "POST",
headers: {
"X-API-Key": "evt_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
recipient_address: "0xYourWalletAddress",
token_symbol: "USDC"
})
}).then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
console.log(`Send USDC to: ${resp.deposit_address}`);
console.log(resp.instructions);
// MCP Tool: et_buy_et10
{
"name": "et_buy_et10",
"arguments": {
"recipient_address": "0xYourWalletAddress",
"token_symbol": "USDC"
}
}
// Response:
// { "success": true, "deposit_address": "0x...", "instructions": "..." }
Example Response
{
"status": "ok",
"intent_id": 376,
"recipient_address": "0xYourWalletAddress",
"deposit_address": "0xDepositAddressReturnedByAPI",
"token_symbol": "USDC",
"chain": "Ethereum",
"chain_id": 1,
"et10_price": "$0.001",
"instructions": "Send USDC to 0x9378... — ET10 will be delivered to 0xYour... automatically."
}
Public Endpoints
No authentication required. Use these for token discovery, price quotes, deposit addresses, and status tracking.
Returns all supported tokens with metadata including chain, address, decimals, and logo URL. ET10 price is fixed at $0.001.
Response Fields
curl https://cymetica.com/api/v1/rst/supported-tokens
import requests
tokens = requests.get("https://cymetica.com/api/v1/rst/supported-tokens").json()
for t in tokens["tokens"][:5]:
print(f"{t['symbol']:6s} {t['name']:20s} {t['chain']}")
const data = await fetch("https://cymetica.com/api/v1/rst/supported-tokens").then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
data.tokens.slice(0, 5).forEach(t =>
console.log(`${t.symbol} - ${t.name} (${t.chain})`)
);
Example Response
{
"tokens": [
{
"rank": 1,
"symbol": "BTC",
"name": "Bitcoin",
"address": "0x...",
"decimals": 8,
"chain": "Ethereum",
"chain_id": 1,
"category": "major",
"logoUrl": "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png"
},
...
],
"rst_price_usd": "0.001"
}
Returns the platform's collection address for the token's chain. Send crypto to this address and ET10 is delivered automatically to the registered recipient address on the intent. For anonymous intents the sending wallet must be that same registered recipient (a different sender is rejected with 403); for authenticated intents you may send from a different wallet — e.g. MetaMask — and delivery still goes to the registered recipient.
Path Parameters
Response Fields
curl https://cymetica.com/api/v1/rst/exchange-address/ETH
addr = requests.get("https://cymetica.com/api/v1/rst/exchange-address/ETH").json()
print(f"Send ETH to: {addr['deposit_address']} on {addr['chain']}")
const addr = await fetch("https://cymetica.com/api/v1/rst/exchange-address/ETH").then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
console.log(`Send ETH to: ${addr.deposit_address} on ${addr.chain}`);
Calculate how many ET10 you'll receive for a given token amount. Uses live CoinGecko prices.
Path Parameters
Query Parameters
Response Fields
curl "https://cymetica.com/api/v1/rst/0xRST_ADDRESS/quote-token?token=ETH&amount=1.5"
quote = requests.get(
"https://cymetica.com/api/v1/rst/0xRST_ADDRESS/quote-token",
params={"token": "ETH", "amount": "1.5"}
).json()
print(f"1.5 ETH (${quote['usd_value']}) = {quote['rst_amount']} ET10")
const quote = await fetch(
"https://cymetica.com/api/v1/rst/0xRST_ADDRESS/quote-token?token=ETH&amount=1.5"
).then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
console.log(`1.5 ETH ($${quote.usd_value}) = ${quote.rst_amount} ET10`);
Example Response
{
"token_symbol": "ETH",
"token_amount": "1.5",
"token_price_usd": "3200.50",
"usd_value": "4800.75",
"rst_amount": "4800750",
"rst_price_usd": "0.001"
}
Check the status of the most recent deposit for a token and recipient. Returns status from the last 2 hours. Use this for polling after sending crypto.
Note: results are scoped to collection wallet + token + recipient and the most recently updated intent is returned. Two simultaneous deposits of the same token to the same recipient therefore collapse to the newest intent — stagger them or use distinct recipients if you need to track both.
Path Parameters
Query Parameters
GET /deposit-intent/{intent_id} with your API key. Omitting recipient or passing a malformed address returns 400.Response Fields
curl "https://cymetica.com/api/v1/rst/deposit-status/ETH?recipient=0xYOUR_ADDRESS"
status = requests.get(
"https://cymetica.com/api/v1/rst/deposit-status/ETH",
params={"recipient": "0xYOUR_ADDRESS"}, # required
).json()
print(f"Status: {status['status']}")
if status.get("tx_hash"):
print(f"Tx: https://etherscan.io/tx/{status['tx_hash']}")
// `recipient` is required — without it the request returns 400.
const status = await fetch("https://cymetica.com/api/v1/rst/deposit-status/ETH?recipient=0xYOUR_ADDRESS").then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
console.log(`Status: ${status.status}`);
if (status.tx_hash) console.log(`Tx: https://etherscan.io/tx/${status.tx_hash}`);
Authenticated Endpoints
These endpoints require authentication: either a Bearer token (JWT session) or an API key via the X-API-Key header. Bots should use X-API-Key — it also skips CSRF validation. Used for creating deposit intents and tracking individual user deposits.
Creates a deposit intent and returns the collection address. The platform watches for deposits and automatically delivers ET10 to the registered recipient address on the intent (not necessarily the sending wallet — see the sender rules above).
Deposit chain vs delivery chain: the chain/chain_id fields describe where you send the payment. ET10 itself is always delivered on Ethereum mainnet, regardless of the deposit chain — your recipient address must be an Ethereum mainnet address.
Request Body
Response Fields
# Bot / programmatic (API key — export ET_API_KEY=evt_... first):
curl -X POST https://cymetica.com/api/v1/rst/deposit-intent \
-H "X-API-Key: $ET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"rst_address":"0xRST_ADDRESS","token_symbol":"ETH"}'
# Browser session (Bearer JWT):
curl -X POST https://cymetica.com/api/v1/rst/deposit-intent \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"rst_address":"0xRST_ADDRESS","token_symbol":"ETH"}'
intent = requests.post(
"https://cymetica.com/api/v1/rst/deposit-intent",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={"rst_address": "0xRST_ADDRESS", "token_symbol": "ETH"}
).json()
print(f"Send ETH to: {intent['deposit_address']}")
const intent = await fetch("https://cymetica.com/api/v1/rst/deposit-intent", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ rst_address: "0xRST_ADDRESS", token_symbol: "ETH" })
}).then(r => { if (!r.ok) throw new Error(r.status); return r.json(); });
console.log(`Send ETH to: ${intent.deposit_address}`);
Check the status of a specific deposit intent by its intent_id. Users can only view their own intents. Recommended for bots: unlike deposit-status/{token} (which resolves by token + recipient and is ambiguous when you have several concurrent intents for the same token and recipient), this endpoint is intent-specific.
curl https://cymetica.com/api/v1/rst/deposit-intent/42 \
-H "X-API-Key: $ET_API_KEY"
# or: -H "Authorization: Bearer YOUR_TOKEN"
status = requests.get(
"https://cymetica.com/api/v1/rst/deposit-intent/42",
headers={"X-API-Key": "evt_YOUR_KEY"} # or Authorization: Bearer YOUR_TOKEN
).json()
print(f"Intent #{status['id']}: {status['status']}")
List all deposit intents for the authenticated user (most recent first, max 50).
curl https://cymetica.com/api/v1/rst/deposit-intents \
-H "Authorization: Bearer YOUR_TOKEN"
Status Tracking
After sending crypto to the deposit address, poll the status endpoint to track progress. The state machine flows through these states:
rst_received and tx_hash populated.Pricing & Conversion Terms
Polling Example
Note: deposit-status/{token} resolves by token + recipient, which is ambiguous if you run multiple concurrent intents for the same token and recipient. Bots should prefer the authenticated per-intent endpoint GET /deposit-intent/{intent_id} (see above, works with X-API-Key).
import time, requests
BASE = "https://cymetica.com/api/v1/rst"
RECIPIENT = "0xYOUR_ADDRESS" # required — scopes the lookup to your intents
# Poll every 10 seconds until completed or failed
while True:
status = requests.get(
f"{BASE}/deposit-status/ETH", params={"recipient": RECIPIENT}
).json()
print(f"Status: {status['status']}")
if status["status"] == "completed":
print(f"Received {status['rst_received']} ET10!")
print(f"Tx: https://etherscan.io/tx/{status['tx_hash']}")
break
elif status["status"] == "failed":
print("Deposit failed — contact support")
break
time.sleep(10)
MCP Integration
7 MCP tools for AI agents using any MCP-compatible client (Claude Code, Cursor, IDE plugins, etc.). Every tool authenticates with the API key from your MCP config (EVENT_TRADER_API_KEY; ET_API_KEY also accepted from v1.1.2) — including et_rst_create_intent.
Claude Desktop Configuration
Add to your claude_desktop_config.json:
{
"mcpServers": {
"event-trader": {
"command": "uvx",
"args": ["cymetica-eventtrader-mcp"],
"env": {
"EVENT_TRADER_API_URL": "https://cymetica.com",
"EVENT_TRADER_API_KEY": "YOUR_API_KEY"
}
}
}
}
Once configured, ask Claude: "List all tokens I can exchange for ET10" or "Quote me 0.1 ETH to ET10".
DCA Bot Skeleton (intent + polling)
A Python skeleton for dollar-cost averaging into ET10. It covers the platform side: quote → create intent → poll by intent_id until delivery. It does not send crypto or schedule runs — step 3 is where you plug in your own wallet library (web3.py, bitcoinlib, solana-py, …) to sign and send the deposit, and recurrence is up to your scheduler (cron, systemd timer, …).
#!/usr/bin/env python3
"""ET10 DCA bot skeleton — intent creation + status polling.
You supply: (a) the wallet signing/sending in step 3, and (b) the
recurring schedule (run this from cron or a timer for true DCA).
"""
import time
import requests
BASE = "https://cymetica.com/api/v1/rst"
RST_ADDRESS = "0xYOUR_RST_ADDRESS"
TOKEN = "ETH"
# Your API key (evt_...) goes in the X-API-Key header — NOT as a Bearer token.
# Bearer is for a JWT session token; an API key sent as Bearer will NOT
# authenticate you.
API_KEY = "YOUR_API_KEY"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
def buy_et10():
# 1. Get an indicative quote (prices at request time — not a locked rate;
# the final ET10 amount is computed from what actually arrives)
quote = requests.get(
f"{BASE}/{RST_ADDRESS}/quote-token",
params={"token": TOKEN, "amount": "0.01"}
).json()
print(f"Quote: 0.01 {TOKEN} = {quote['rst_amount']} ET10 (${quote['usd_value']})")
# 2. Create deposit intent (X-API-Key authenticated)
intent = requests.post(
f"{BASE}/deposit-intent",
headers=HEADERS,
json={"rst_address": RST_ADDRESS, "token_symbol": TOKEN}
).json()
intent_id = intent["intent_id"]
# intent["chain"] is the DEPOSIT chain; ET10 is delivered on Ethereum mainnet.
print(f"Intent #{intent_id}: send {TOKEN} to {intent['deposit_address']} ({intent['chain']})")
# 3. YOUR CODE HERE: sign + send 0.01 TOKEN to intent["deposit_address"]
# with your wallet library. Nothing happens until the deposit lands.
# 4. Poll THIS intent by id — unambiguous even with multiple concurrent
# intents for the same token/recipient.
for _ in range(60): # 10 minutes max
status = requests.get(
f"{BASE}/deposit-intent/{intent_id}", headers=HEADERS
).json()
if status["status"] == "completed":
print(f"Received {status['rst_received']} ET10!")
print(f"Tx: https://etherscan.io/tx/{status['tx_hash']}")
return True
elif status["status"] == "failed":
print("Failed — deposited funds are safe; contact support with the intent id")
return False
time.sleep(10)
return False
if __name__ == "__main__":
buy_et10()
Troubleshooting
Error Codes
| Code | Meaning | Action |
|---|---|---|
| 400 | Invalid token symbol or amount | Check supported tokens list |
| 400 | Token coming soon | Chain not yet supported for this token |
| 401 | Unauthorized | Add a Bearer token or X-API-Key for auth-required endpoints |
| 404 | ET10 not found | Verify the ET10 contract address |
| 429 | Rate limited | Wait and retry. Public: 30/min, Intents: 10/min |
| 503 | Exchange address unavailable | Chain wallet not configured. Try again later. |
| 503 | Price unavailable | CoinGecko price feed down. Retry in 60s. |
Rate Limits
| Endpoint | Limit | Window |
|---|---|---|
| supported-tokens | No limit | — |
| exchange-address | 30 requests | Per IP per minute |
| quote-token | 30 requests | Per IP per minute |
| deposit-status | 60 requests | Per IP per minute |
| deposit-intent | 10 requests | Per user per minute |