Only src/api/ (standalone compute marketplace server) stays private. Everything else is standard infrastructure the gateway needs to compile and run. CI passes: typecheck, 135 tests, build all green. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50 KiB
Clodds API
This document describes the HTTP and WebSocket endpoints exposed by the Clodds gateway.
Base URL
By default the gateway binds to loopback and listens on port 18789.
http://127.0.0.1:18789
Authentication and security
- HTTP endpoints do not enforce authentication by default. Protect the gateway with network controls or a reverse proxy if you expose it publicly.
- WebChat supports an optional token. Set
WEBCHAT_TOKENand send it in the WebSocket auth message. - Webhooks require HMAC signatures by default. See the webhook section below.
What is this API for?
Skills and agents running inside Clodds call services directly — no HTTP needed. The REST API is for everything external: dashboards, mobile apps, automation scripts, Telegram/Discord bots, monitoring (Grafana/Datadog), AI agent integrations (MCP tools, LangChain), multi-instance orchestration, and copy trading platforms. See API_REFERENCE.md for detailed examples.
HTTP endpoints
GET /health
Basic health check.
Response:
{ "status": "ok", "timestamp": 1730000000000 }
GET /
API info and supported endpoints.
Response:
{
"name": "clodds",
"version": "0.3.10",
"description": "AI assistant for prediction markets",
"endpoints": { "websocket": "/ws", "webchat": "/chat", "health": "/health" }
}
GET /webchat
Returns a simple HTML client that connects to the WebChat WebSocket endpoint (/chat).
POST /webhook or /webhook/*
Generic webhook endpoint for automation hooks.
Headers:
x-webhook-signatureorx-hub-signature-256(required by default)
Signature:
- HMAC SHA-256 hex digest of the raw request body using the webhook secret.
- To disable signature requirements, set
CLODDS_WEBHOOK_REQUIRE_SIGNATURE=0.
Responses:
200 { "ok": true }on success401for missing/invalid signatures404for unknown webhook paths429if rate limited
POST /channels/:platform
Channel webhook entrypoint for platforms like Teams, Google Chat, etc.
Behavior:
- Forwards the JSON body to the configured channel adapter.
- Returns
404if that platform handler is not configured.
GET /market-index/search
Search the market index (requires marketIndex.enabled).
Query parameters:
q(string, required): search textplatform(string, optional):polymarket|kalshi|manifold|metaculuslimit(number, optional)maxCandidates(number, optional)minScore(number, optional)platformWeights(JSON string, optional)
Response:
{
"results": [
{
"score": 0.8421,
"market": {
"platform": "polymarket",
"id": "123",
"slug": "will-x-happen",
"question": "...",
"description": "...",
"url": "...",
"status": "open",
"endDate": "2026-01-01T00:00:00.000Z",
"resolved": false,
"volume24h": 1234,
"liquidity": 5678,
"openInterest": 910,
"predictions": 42
}
}
]
}
GET /market-index/stats
Market index stats (requires marketIndex.enabled).
Query parameters:
platforms(comma-separated list, optional)
POST /market-index/sync
Trigger a manual market index sync (requires marketIndex.enabled).
Body (JSON):
platforms(array or comma-separated string, optional)limitPerPlatform(number, optional)status(open|closed|settled|all, optional)excludeSports(boolean, optional)minVolume24h(number, optional)minLiquidity(number, optional)minOpenInterest(number, optional)minPredictions(number, optional)excludeResolved(boolean, optional)prune(boolean, optional)staleAfterMs(number, optional)
Response:
{ "result": { "indexed": 123, "byPlatform": { "polymarket": 100 } } }
GET /api/ticks/:platform/:marketId
Get historical tick data (requires tickRecorder.enabled).
Query parameters:
outcomeId(string, optional): filter by outcomestartTime(number, optional): Unix timestamp in ms (default: 24h ago)endTime(number, optional): Unix timestamp in ms (default: now)limit(number, optional): max results (default: 1000)
Response:
{
"ticks": [
{
"time": "2026-02-02T12:00:00.000Z",
"platform": "polymarket",
"marketId": "0x123",
"outcomeId": "yes",
"price": 0.55,
"prevPrice": 0.54
}
]
}
GET /api/ohlc/:platform/:marketId
Get OHLC candle data (requires tickRecorder.enabled).
Query parameters:
outcomeId(string, required): outcome IDinterval(string, optional):1m|5m|15m|1h|4h|1d(default:1h)startTime(number, optional): Unix timestamp in ms (default: 7d ago)endTime(number, optional): Unix timestamp in ms (default: now)
Response:
{
"candles": [
{
"time": 1706500000000,
"open": 0.50,
"high": 0.56,
"low": 0.49,
"close": 0.55,
"tickCount": 42
}
]
}
GET /api/orderbook-history/:platform/:marketId
Get historical orderbook snapshots (requires tickRecorder.enabled).
Query parameters:
outcomeId(string, optional): filter by outcomestartTime(number, optional): Unix timestamp in ms (default: 1h ago)endTime(number, optional): Unix timestamp in ms (default: now)limit(number, optional): max results (default: 100)
Response:
{
"snapshots": [
{
"time": "2026-02-02T12:00:00.000Z",
"platform": "polymarket",
"marketId": "0x123",
"outcomeId": "yes",
"bids": [[0.54, 1000], [0.53, 500]],
"asks": [[0.56, 800], [0.57, 1200]],
"spread": 0.02,
"midPrice": 0.55
}
]
}
GET /api/tick-recorder/stats
Get tick recorder statistics (requires tickRecorder.enabled).
Response:
{
"stats": {
"ticksRecorded": 150000,
"orderbooksRecorded": 50000,
"ticksInBuffer": 45,
"orderbooksInBuffer": 12,
"lastFlushTime": 1706500000000,
"dbConnected": true,
"platforms": ["polymarket", "kalshi"]
}
}
GET /api/tick-streamer/stats
Get tick streamer statistics.
Response:
{
"stats": {
"connectedClients": 5,
"totalSubscriptions": 12,
"ticksBroadcast": 45000,
"orderbooksBroadcast": 15000,
"uptime": 3600000
}
}
GET /api/features/:platform/:marketId
Get computed trading features for a specific market.
Query parameters:
outcomeId(string, optional): specific outcome
Response:
{
"features": {
"timestamp": 1706500000000,
"platform": "polymarket",
"marketId": "0x123",
"outcomeId": "yes",
"tick": {
"price": 0.55,
"priceChange": 0.01,
"priceChangePct": 1.85,
"momentum": 0.03,
"velocity": 0.001,
"volatility": 0.015,
"volatilityPct": 1.5,
"tickCount": 150,
"tickIntensity": 2.5,
"vwap": null
},
"orderbook": {
"spread": 0.02,
"spreadPct": 3.6,
"midPrice": 0.55,
"bidDepth": 5000,
"askDepth": 4500,
"totalDepth": 9500,
"imbalance": 0.053,
"imbalanceRatio": 1.11,
"bestBid": 0.54,
"bestAsk": 0.56,
"bestBidSize": 1000,
"bestAskSize": 800,
"weightedBidPrice": 0.535,
"weightedAskPrice": 0.565,
"bidDepthAt1Pct": 2000,
"askDepthAt1Pct": 1800,
"bidDepthAt5Pct": 4500,
"askDepthAt5Pct": 4000
},
"signals": {
"buyPressure": 0.62,
"sellPressure": 0.38,
"trendStrength": 0.15,
"liquidityScore": 0.72
}
}
}
GET /api/features
Get all computed features for all tracked markets.
Response:
{
"snapshots": [
{
"timestamp": 1706500000000,
"platform": "polymarket",
"marketId": "0x123",
"outcomeId": "yes",
"features": { ... }
}
],
"count": 15
}
GET /api/features/stats
Get feature engineering service statistics.
Response:
{
"stats": {
"marketsTracked": 15,
"ticksProcessed": 45000,
"orderbooksProcessed": 12000
}
}
WebSocket endpoints
WS /ws
Development WebSocket endpoint. Currently echoes incoming JSON with a wrapper:
{ "type": "res", "id": "<client id>", "ok": true, "payload": { "echo": <message> } }
WS /api/ticks/stream (Tick Streaming)
Real-time tick data streaming via WebSocket. Subscribe to specific markets and receive live price/orderbook updates.
Client messages:
// Subscribe to a market (ticks enabled by default, orderbook opt-in)
{ "type": "subscribe", "platform": "polymarket", "marketId": "0x123", "ticks": true, "orderbook": true }
// Unsubscribe
{ "type": "unsubscribe", "platform": "polymarket", "marketId": "0x123" }
// Ping (keepalive)
{ "type": "ping" }
Server messages:
// Subscription confirmed
{ "type": "subscribed", "platform": "polymarket", "marketId": "0x123", "ticks": true, "orderbook": true }
// Price tick
{ "type": "tick", "platform": "polymarket", "marketId": "0x123", "outcomeId": "yes", "price": 0.55, "prevPrice": 0.54, "timestamp": 1706500000000 }
// Orderbook update
{ "type": "orderbook", "platform": "polymarket", "marketId": "0x123", "outcomeId": "yes", "bids": [[0.54, 1000]], "asks": [[0.56, 800]], "spread": 0.02, "midPrice": 0.55, "timestamp": 1706500000000 }
// Pong (keepalive response)
{ "type": "pong", "timestamp": 1706500000000 }
// Error
{ "type": "error", "message": "Max subscriptions reached", "code": "MAX_SUBSCRIPTIONS" }
Example usage (JavaScript):
const ws = new WebSocket('ws://localhost:18789/api/ticks/stream');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'subscribe',
platform: 'polymarket',
marketId: '0x123abc',
ticks: true,
orderbook: true
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'tick') {
console.log(`Price: ${msg.price}, Change: ${msg.price - msg.prevPrice}`);
} else if (msg.type === 'orderbook') {
console.log(`Spread: ${msg.spread}, Mid: ${msg.midPrice}`);
}
};
WS /chat (WebChat)
WebChat WebSocket endpoint used by /webchat.
Client messages:
auth:{ "type": "auth", "token": "<WEBCHAT_TOKEN>", "userId": "web-123" }message:{ "type": "message", "text": "hi", "attachments": [] }edit:{ "type": "edit", "messageId": "<id>", "text": "new text" }delete:{ "type": "delete", "messageId": "<id>" }
Server messages:
connected,authenticated,ack,message,edit,delete,error
Attachment fields (if provided):
type:image|video|audio|document|voice|stickerurlordata(base64)mimeType,filename,size,width,height,duration,caption
REST /api/chat/sessions (WebChat)
Session management and message history for WebChat.
GET /api/chat/sessions?userId=<id>— list sessions (returns id, title, updatedAt, messageCount, lastMessage)GET /api/chat/sessions/:id— load session with messages (supports?limit=N&before=timestampfor pagination)POST /api/chat/sessions— create new session ({ "userId": "web-123" })PATCH /api/chat/sessions/:id— rename session ({ "title": "New title" })DELETE /api/chat/sessions/:id— delete session and all its messages
Messages are stored in a dedicated messages table (one row per message, append-only). Chat history is unlimited — the LLM receives the last 20 messages plus a compressed summary of earlier conversation for context continuity.
Cloudflare Worker API
The lightweight Clodds Worker (apps/clodds-worker) exposes a separate REST API on Cloudflare's edge network.
Base URL
https://clodds-worker.<account>.workers.dev
GET /api/health
Health check with service status.
Response:
{
"status": "ok",
"version": "0.3.10",
"timestamp": "2026-01-29T...",
"services": {
"telegram": true,
"discord": false,
"slack": false,
"kalshi": true,
"anthropic": true
}
}
GET /api/markets/search
Search markets across platforms.
Query parameters:
qorquery(string, required): search textplatform(string, optional):polymarket|kalshi|manifoldlimit(number, optional, max 50)
Response:
{
"markets": [
{
"id": "...",
"platform": "polymarket",
"question": "Will X happen?",
"outcomes": [{ "id": "...", "name": "Yes", "price": 0.45 }],
"volume24h": 12345,
"url": "https://polymarket.com/..."
}
],
"count": 10
}
GET /api/markets/:platform/:id
Get a specific market by platform and ID.
Response:
{ "market": { ... } }
GET /api/markets/:platform/:id/orderbook
Get orderbook for a market (Polymarket, Kalshi only).
Response:
{
"orderbook": {
"platform": "polymarket",
"marketId": "...",
"bids": [[0.45, 1000], [0.44, 500]],
"asks": [[0.46, 800], [0.47, 1200]],
"spread": 0.01,
"midPrice": 0.455,
"timestamp": 1706500000000
}
}
GET /api/arbitrage/scan
Scan for arbitrage opportunities.
Query parameters:
min_edge(number, optional): minimum edge % (default 1)platforms(string, optional): comma-separated listlimit(number, optional, max 50)
Response:
{
"opportunities": [
{
"id": "polymarket-abc123",
"platform": "polymarket",
"marketId": "abc123",
"marketQuestion": "Will X?",
"yesPrice": 0.48,
"noPrice": 0.49,
"edgePct": 0.03,
"mode": "internal",
"foundAt": 1706500000000
}
],
"count": 5,
"scannedPlatforms": ["polymarket", "kalshi"],
"minEdge": 1
}
GET /api/arbitrage/recent
Get recently found arbitrage opportunities from database.
Query parameters:
limit(number, optional, max 100)
Webhook endpoints
POST /webhook/telegram- Telegram Bot API webhookPOST /webhook/discord- Discord Interactions endpointPOST /webhook/slack- Slack Events API endpoint
See apps/clodds-worker/README.md for webhook setup instructions.
Programmatic Trading Modules
The following modules can be imported and used directly in your TypeScript/JavaScript code.
EVM DEX Trading
import { executeUniswapSwap, getUniswapQuote, executeOneInchSwap, compareDexRoutes } from 'clodds/evm';
// Get quote from Uniswap V3
const quote = await getUniswapQuote({
chain: 'ethereum', // 'ethereum' | 'arbitrum' | 'optimism' | 'base' | 'polygon'
inputToken: 'USDC',
outputToken: 'WETH',
amount: '1000',
slippageBps: 50,
});
// Execute swap with MEV protection
const result = await executeUniswapSwap({
chain: 'ethereum',
inputToken: 'USDC',
outputToken: 'WETH',
amount: '1000',
});
// Compare Uniswap vs 1inch for best route
const comparison = await compareDexRoutes({
chain: 'ethereum',
fromToken: 'USDC',
toToken: 'WETH',
amount: '1000',
});
console.log(`Best route: ${comparison.best}, saves ${comparison.savings}`);
MEV Protection
import { createMevProtectionService, sendFlashbotsProtect, submitJitoBundle } from 'clodds/execution/mev-protection';
// Create protection service
const mev = createMevProtectionService({
level: 'aggressive', // 'none' | 'basic' | 'aggressive'
maxPriceImpact: 3,
jitoTipLamports: 10000,
});
// Send EVM transaction via Flashbots Protect
const result = await mev.sendEvmTransaction('ethereum', signedTx);
// Submit Solana bundle via Jito
const bundle = await mev.createSolanaBundle(transactions, payerPubkey);
await mev.submitSolanaBundle(bundle);
Whale Tracking (Polymarket)
import { createWhaleTracker, getMarketWhaleActivity } from 'clodds/feeds/polymarket/whale-tracker';
const tracker = createWhaleTracker({
minTradeSize: 10000, // $10k minimum
minPositionSize: 50000, // $50k to track
enableRealtime: true,
});
tracker.on('trade', (trade) => {
console.log(`Whale ${trade.side} $${trade.usdValue} on ${trade.marketQuestion}`);
});
tracker.on('positionOpened', (position) => {
console.log(`New position: ${position.address} - $${position.usdValue}`);
});
await tracker.start();
// Get whale activity for a specific market
const activity = await getMarketWhaleActivity(marketId);
console.log(`Buy volume: $${activity.buyVolume}, Sell volume: $${activity.sellVolume}`);
Crypto Whale Tracking (Multi-Chain)
import { createCryptoWhaleTracker } from 'clodds/feeds/crypto/whale-tracker';
const tracker = createCryptoWhaleTracker({
chains: ['solana', 'ethereum', 'polygon', 'arbitrum', 'base', 'optimism'],
thresholds: {
solana: 10000, // $10k+ on Solana
ethereum: 50000, // $50k+ on ETH
polygon: 5000, // $5k+ on Polygon
arbitrum: 10000,
base: 10000,
optimism: 10000,
},
birdeyeApiKey: process.env.BIRDEYE_API_KEY, // For Solana
alchemyApiKey: process.env.ALCHEMY_API_KEY, // For EVM chains
});
// Real-time transaction events
tracker.on('transaction', (tx) => {
console.log(`${tx.chain}: ${tx.type} $${tx.usdValue} from ${tx.wallet}`);
console.log(` Token: ${tx.token}, Amount: ${tx.amount}`);
});
// Whale alerts (above threshold)
tracker.on('alert', (alert) => {
console.log(`WHALE ALERT: ${alert.message}`);
});
// Watch specific wallets
tracker.watchWallet('solana', 'ABC123...', { label: 'Known Whale' });
tracker.watchWallet('ethereum', '0x1234...', { label: 'Smart Money' });
await tracker.start();
// Query methods
const topSolWhales = tracker.getTopWhales('solana', 10);
const recentEthTxs = tracker.getRecentTransactions('ethereum', 100);
const wallet = tracker.getWallet('solana', 'ABC123...');
Supported Chains:
| Chain | Provider | Features |
|---|---|---|
| Solana | Birdeye WebSocket | Token transfers, swaps, NFTs |
| Ethereum | Alchemy WebSocket | ERC-20, ETH transfers |
| Polygon | Alchemy WebSocket | MATIC, tokens |
| Arbitrum | Alchemy WebSocket | L2 activity |
| Base | Alchemy WebSocket | Coinbase L2 |
| Optimism | Alchemy WebSocket | OP ecosystem |
Transaction Types: transfer, swap, nft, stake, unknown
Copy Trading
import { createCopyTradingService, findBestAddressesToCopy } from 'clodds/trading/copy-trading';
// Find profitable addresses to copy
const topTraders = await findBestAddressesToCopy(whaleTracker, {
minWinRate: 55,
minTrades: 10,
minAvgReturn: 5,
});
const copyTrader = createCopyTradingService(whaleTracker, execution, {
followedAddresses: topTraders.map(t => t.address),
sizingMode: 'fixed', // 'fixed' | 'proportional' | 'percentage'
fixedSize: 100, // $100 per trade
maxPositionSize: 500, // Max $500 per market
copyDelayMs: 5000, // 5s delay before copying
dryRun: true, // Start in dry run mode
// Stop-loss / Take-profit monitoring
stopLossPct: 10, // Exit at 10% loss
takeProfitPct: 20, // Exit at 20% profit
});
copyTrader.on('tradeCopied', (trade) => {
console.log(`Copied: ${trade.side} ${trade.size} @ ${trade.entryPrice}`);
});
// SL/TP events
copyTrader.on('positionClosed', (trade, reason) => {
console.log(`Position closed: ${reason} at ${trade.exitPrice}`);
// reason: 'stop_loss' | 'take_profit' | 'manual'
});
copyTrader.start();
// Follow/unfollow addresses dynamically
copyTrader.follow('0x...');
copyTrader.unfollow('0x...');
SL/TP Monitoring:
- 5-second price polling interval
- Automatic position exit when thresholds hit
- Events emitted for position closures with reason
Smart Order Routing
import { createSmartRouter, quickPriceCompare } from 'clodds/execution/smart-router';
const router = createSmartRouter(feeds, {
mode: 'balanced', // 'best_price' | 'best_liquidity' | 'lowest_fee' | 'balanced'
enabledPlatforms: ['polymarket', 'kalshi'],
maxSlippage: 1,
preferMaker: true,
allowSplitting: true,
});
// Find best route for an order
const result = await router.findBestRoute({
marketId: 'trump-win-2024',
side: 'buy',
size: 1000,
limitPrice: 0.52,
});
console.log(`Best platform: ${result.bestRoute.platform}`);
console.log(`Net price: ${result.bestRoute.netPrice}`);
console.log(`Savings: $${result.totalSavings}`);
// Quick price comparison
const prices = await quickPriceCompare(feeds, 'trump-win-2024');
console.log(prices); // { polymarket: 0.52, kalshi: 0.54 }
Authentication (OAuth, Copilot, Google, Qwen)
import {
OAuthClient,
interactiveOAuth,
createAnthropicOAuth,
createOpenAIOAuth,
createGoogleOAuth
} from 'clodds/auth/oauth';
import { CopilotAuthClient, interactiveCopilotAuth } from 'clodds/auth/copilot';
import { GoogleAuthClient, GeminiClient, interactiveGoogleAuth } from 'clodds/auth/google';
import { QwenAuthClient, QwenClient } from 'clodds/auth/qwen';
// OAuth for Anthropic/OpenAI
const anthropicOAuth = createAnthropicOAuth('client-id', 'client-secret');
const tokens = await interactiveOAuth({
provider: 'anthropic',
clientId: 'your-client-id',
scopes: ['api:read', 'api:write'],
});
// GitHub Copilot authentication
const copilotAuth = new CopilotAuthClient();
await interactiveCopilotAuth(); // Interactive device code flow
const headers = await copilotAuth.getHeaders();
// Google/Gemini authentication
const googleAuth = new GoogleAuthClient({ projectId: 'my-project' });
await interactiveGoogleAuth();
const gemini = new GeminiClient({ projectId: 'my-project' });
const response = await gemini.generateContent('gemini-pro', 'Hello world');
// Qwen/DashScope authentication
const qwen = new QwenClient({ apiKey: process.env.DASHSCOPE_API_KEY });
const result = await qwen.generate('qwen-turbo', 'Hello');
OpenTelemetry Diagnostics
import {
initTelemetry,
TelemetryService,
LLMInstrumentation,
createLLMInstrumentation
} from 'clodds/telemetry';
// Initialize telemetry
const telemetry = initTelemetry({
enabled: true,
serviceName: 'clodds',
otlpEndpoint: 'http://localhost:4318', // OTLP collector
jaegerEndpoint: 'http://localhost:14268', // Jaeger
metricsPort: 9090, // Prometheus metrics
sampleRate: 1.0,
});
// Create LLM instrumentation
const llmInstr = createLLMInstrumentation();
// Trace LLM completion
const { result, span } = await llmInstr.traceCompletion(
'anthropic',
'claude-3-5-sonnet',
() => provider.complete({ model, messages }),
{ inputTokens: 100, userId: 'user-123' }
);
// Record token usage
llmInstr.recordTokenUsage('anthropic', 'claude-3-5-sonnet', 100, 500);
// Manual tracing
const span = telemetry.startTrace('my-operation', { custom: 'attr' });
telemetry.addEvent(span, 'checkpoint');
telemetry.endSpan(span, 'ok');
// Metrics
telemetry.recordCounter('requests_total', 1, { endpoint: '/api' });
telemetry.recordHistogram('request_duration_ms', 150);
// Start Prometheus metrics server
telemetry.startMetricsServer(9090);
Task Runner Extension
import { createTaskRunner, TaskRunner, TaskDefinition } from 'clodds/extensions/task-runner';
const runner = createTaskRunner({
maxConcurrent: 4,
defaultTimeout: 60000,
planningModel: 'claude-3-5-sonnet',
}, provider);
// Plan tasks from high-level goal
const tasks = await runner.planTasks('Build a REST API with user authentication');
// Execute tasks with dependency resolution
const results = await runner.executeTasks(tasks, '/path/to/workdir');
// Built-in executors: shell, file, http, llm, transform
const shellTask: TaskDefinition = {
id: 'build',
name: 'Build project',
type: 'atomic',
executor: 'shell',
input: { command: 'npm', args: ['run', 'build'] },
};
// Register custom executor
runner.registerExecutor({
name: 'custom',
execute: async (task, context) => {
// Custom logic
return { success: true };
},
});
Open Prose Extension
import { createOpenProseExtension } from 'clodds/extensions/open-prose';
const prose = await createOpenProseExtension({
enabled: true,
enableHistory: true,
maxHistoryEntries: 100,
});
// Create and edit documents
const doc = await prose.createDocument('My Article', '# Draft\n\nContent here...', 'markdown');
await prose.updateDocument(doc.id, '# Updated\n\nNew content', 'Major revision');
// AI-assisted editing (requires provider)
const { document, changes } = await prose.aiEdit(doc.id, 'Make it more concise', provider);
const completion = await prose.aiComplete(doc.id, 50, provider);
const summary = await prose.aiSummarize(doc.id, provider);
const { document: rewritten } = await prose.aiRewrite(doc.id, 'formal', provider);
// Version history
const history = await prose.getHistory(doc.id);
await prose.restoreVersion(doc.id, 3);
// Export
const html = await prose.exportDocument(doc.id, 'html');
Auto-Arbitrage Execution
import { createOpportunityExecutor } from 'clodds/opportunity/executor';
const executor = createOpportunityExecutor(finder, execution, {
minEdge: 1.0, // Minimum 1% edge
minLiquidity: 500, // Minimum $500 liquidity
maxPositionSize: 100, // Max $100 per trade
maxDailyLoss: 500, // Stop after $500 daily loss
maxConcurrentPositions: 3,
preferMakerOrders: true,
dryRun: true, // Start in dry run mode
});
executor.on('executed', (opp, result) => {
console.log(`Executed: ${opp.id}, profit: $${result.actualProfit}`);
});
executor.on('skipped', (opp, reason) => {
console.log(`Skipped: ${reason}`);
});
executor.start();
// View stats
const stats = executor.getStats();
console.log(`Win rate: ${stats.winRate}%, Total P&L: $${stats.totalProfit - stats.totalLoss}`);
External Data Feeds
import {
getFedWatchProbabilities,
get538Probability,
getRCPPollingAverage,
analyzeEdge,
calculateKelly
} from 'clodds/feeds/external';
// Get Fed rate probabilities
const fedWatch = await getFedWatchProbabilities();
console.log(fedWatch.get('January 2026')); // 0.85
// Get election model probability
const model = await get538Probability('Trump president');
console.log(model?.probability); // 0.52
// Get polling average
const polls = await getRCPPollingAverage('Trump vs Biden');
console.log(polls?.probability); // 0.48
// Analyze edge vs market price
const edge = await analyzeEdge(
'market-123',
'Will Trump win?',
0.45, // market price
'politics'
);
console.log(`Fair value: ${edge.fairValue}, Edge: ${edge.edgePct}%`);
// Calculate Kelly bet size
const kelly = calculateKelly(0.45, 0.52, 10000);
console.log(`Half Kelly: $${kelly.halfKelly}`);
Percolator Endpoints
On-chain Solana perpetual futures via Percolator protocol. Requires PERCOLATOR_ENABLED=true.
GET /api/percolator/status
Get current market state (oracle price, open interest, funding rate, spread).
Response:
{
"oraclePrice": 142.50,
"totalOpenInterest": 1250000,
"vault": 5000000,
"insuranceFund": 250000,
"fundingRate": 3,
"bestBid": { "lpIndex": 0, "priceUsd": 142.29 },
"bestAsk": { "lpIndex": 0, "priceUsd": 142.71 },
"spreadBps": 29.5,
"lastCrankSlot": 298456123
}
GET /api/percolator/positions
Get user's open Percolator positions.
Response:
{
"positions": [
{
"accountIndex": 5,
"side": "LONG",
"size": 100.00,
"entryPrice": 140.50,
"capital": 500.00,
"pnl": 14.28
}
]
}
POST /api/percolator/trade
Execute a Percolator trade (long/short).
Request:
{
"direction": "long",
"size": 100
}
Response:
{
"success": true,
"signature": "5UxM...",
"slot": 298456200
}
POST /api/percolator/deposit
Deposit USDC collateral.
Request: { "amount": 500 }
POST /api/percolator/withdraw
Withdraw USDC collateral.
Request: { "amount": 100 }
Security Shield Endpoints
Code scanning, address safety checks, and transaction validation. Always available (no env vars required).
POST /api/shield/scan
Scan code or plugin for malicious patterns.
Request:
{
"code": "const x = require('child_process').exec(userInput);"
}
Response:
{
"riskScore": 85,
"findings": [
{ "category": "shell_exec", "severity": "critical", "pattern": "child_process.exec with user input" }
],
"entropy": 4.2
}
POST /api/shield/check
Check address safety (auto-detects Solana/EVM).
Request: { "address": "0x..." }
Response:
{
"safe": false,
"chain": "ethereum",
"flags": ["known_drainer", "inferno_drainer"],
"riskLevel": "critical"
}
POST /api/shield/validate
Pre-flight transaction validation.
Request:
{
"destination": "0x...",
"amount": 1000,
"token": "USDC"
}
GET /api/shield/stats
Scanner statistics (total scans, threats blocked, scam DB size).
Token Audit Endpoints
GoPlus-powered token security analysis.
GET /api/audit/:address
Audit a token contract. Auto-detects chain (base58 = Solana, 0x = EVM).
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
chain |
string | No | Override chain: ethereum, bsc, polygon, arbitrum, base, solana, etc. |
Response:
{
"address": "0x...",
"chain": "ethereum",
"riskScore": 35,
"flags": {
"isHoneypot": false,
"hasMintFunction": true,
"hasBlacklist": false,
"isProxy": false,
"topHolderConcentration": 0.42
},
"liquidity": 1250000,
"holders": 5420
}
GET /api/audit/:address/safe
Quick boolean safety check. Returns { "address": "...", "chain": "...", "safe": true }.
DCA Endpoints
Dollar-cost averaging across 16 platforms.
GET /api/dca/orders
List active DCA orders.
Response:
{
"orders": [
{
"id": "dca_abc123",
"platform": "polymarket",
"status": "active",
"totalAmount": 1000,
"amountPerCycle": 50,
"intervalSec": 3600,
"cyclesCompleted": 8,
"cyclesRemaining": 12,
"totalSpent": 400,
"createdAt": 1706500000000
}
]
}
GET /api/dca/:id
Get a single DCA order by ID.
POST /api/dca/create
Create a new DCA order.
Request:
{
"platform": "polymarket",
"tokenId": "0x...",
"totalAmount": 1000,
"amountPerCycle": 50,
"intervalSec": 3600,
"price": 0.55,
"side": "buy"
}
POST /api/dca/:id/pause
Pause a running DCA order.
POST /api/dca/:id/resume
Resume a paused DCA order.
DELETE /api/dca/:id
Cancel a DCA order.
TWAP Endpoints
All endpoints require auth. Prefix: /api/twap.
| Method | Path | Description |
|---|---|---|
| GET | /api/twap/orders | List all TWAP orders |
| GET | /api/twap/:id | Get specific TWAP order |
| POST | /api/twap/create | Create TWAP order |
| POST | /api/twap/:id/pause | Pause a TWAP order |
| POST | /api/twap/:id/resume | Resume a TWAP order |
| DELETE | /api/twap/:id | Cancel a TWAP order |
Bracket Order Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/bracket/orders | List all bracket orders |
| GET | /api/bracket/:id | Get specific bracket order |
| POST | /api/bracket/create | Create bracket order (entry + TP + SL) |
| POST | /api/bracket/:id/cancel | Cancel bracket order |
| GET | /api/bracket/stats | Get bracket statistics |
Trigger Order Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/triggers/orders | List all trigger orders |
| GET | /api/triggers/:id | Get specific trigger order |
| POST | /api/triggers/create | Create trigger order |
| DELETE | /api/triggers/:id | Cancel trigger order |
| POST | /api/triggers/:id/pause | Pause trigger order |
| POST | /api/triggers/:id/resume | Resume trigger order |
Copy Trading Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/copy-trading/leaders | List tracked leaders |
| POST | /api/copy-trading/leaders | Add leader wallet |
| DELETE | /api/copy-trading/leaders/:address | Remove leader |
| GET | /api/copy-trading/positions | List copied positions |
| GET | /api/copy-trading/leaders/:address/positions | Leader's positions |
| GET | /api/copy-trading/leaders/:address/stats | Leader performance |
| POST | /api/copy-trading/start | Start copy trading |
| POST | /api/copy-trading/stop | Stop copy trading |
| GET | /api/copy-trading/status | Service status |
| GET | /api/copy-trading/stats | Aggregate stats |
| PUT | /api/copy-trading/config | Update config |
Opportunity Finder Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/opportunities | List opportunities |
| GET | /api/opportunities/:id | Get specific opportunity |
| GET | /api/opportunities/history | Past opportunities |
| GET | /api/opportunities/stats | Finder statistics |
| GET | /api/opportunities/linked-markets | Linked markets |
| POST | /api/opportunities/scan | Manual scan |
| POST | /api/opportunities/start | Start scanning |
| POST | /api/opportunities/stop | Stop scanning |
| PUT | /api/opportunities/config | Update config |
| GET | /api/opportunities/platforms | Available platforms |
| POST | /api/opportunities/:id/execute | Execute opportunity |
| POST | /api/opportunities/:id/simulate | Simulate execution |
| GET | /api/opportunities/executions | Execution results |
| POST | /api/opportunities/auto-execute/start | Start auto-execute |
Whale Tracker Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/whales/wallets | List tracked wallets |
| POST | /api/whales/wallets | Add wallet |
| DELETE | /api/whales/wallets/:address | Remove wallet |
| GET | /api/whales/:address/positions | Wallet positions |
| GET | /api/whales/:address/history | Wallet history |
| POST | /api/whales/:address/record-close | Record closed position |
| GET | /api/whales/stats | Tracker statistics |
| GET | /api/whales/leaderboard | Performance leaderboard |
| POST | /api/whales/start | Start tracking |
| POST | /api/whales/stop | Stop tracking |
| GET | /api/whales/status | Service status |
| PUT | /api/whales/config | Update config |
| GET | /api/whales/activity | Recent activity |
Risk Engine Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/risk/assess | Assess trade risk |
| GET | /api/risk/limits/:userId | Get user risk limits |
| PUT | /api/risk/limits/:userId | Update user limits |
| POST | /api/risk/pnl | Record PnL entry |
| GET | /api/risk/report/:userId | Full risk report |
| GET | /api/risk/stats | Engine statistics |
Smart Router Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/routing/quote | Find best route |
| POST | /api/routing/quotes | Get all quotes |
| POST | /api/routing/compare | Compare routes |
| PUT | /api/routing/config | Update config |
Feeds Manager Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/feeds/cache-stats | Cache statistics |
| POST | /api/feeds/cache/clear | Clear cache |
| GET | /api/feeds/search | Search markets |
| GET | /api/feeds/news | Latest news |
| GET | /api/feeds/news/search | Search news |
| GET | /api/feeds/market/:marketId | Market data |
| GET | /api/feeds/price/:platform/:marketId | Current price |
| GET | /api/feeds/orderbook/:platform/:marketId | Orderbook |
| POST | /api/feeds/analyze-edge | Analyze edge |
| POST | /api/feeds/kelly | Kelly criterion |
Monitoring Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/monitoring/health | System health |
| GET | /api/monitoring/providers | Provider health |
| GET | /api/monitoring/process | Process info |
Alt Data Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/alt-data/signals | Recent signals |
| GET | /api/alt-data/sentiment/:marketId | Market sentiment |
| GET | /api/alt-data/stats | Service stats |
Alerts Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/alerts | List alerts |
| GET | /api/alerts/:id | Get alert |
| POST | /api/alerts/price | Create price alert |
| POST | /api/alerts/price-change | Create price-change alert |
| POST | /api/alerts/volume | Create volume alert |
| PUT | /api/alerts/:id/enable | Enable alert |
| PUT | /api/alerts/:id/disable | Disable alert |
| DELETE | /api/alerts/:id | Delete alert |
| POST | /api/alerts/start-monitoring | Start monitoring |
| POST | /api/alerts/stop-monitoring | Stop monitoring |
Execution Queue Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/queue/jobs/:id | Job status |
| POST | /api/queue/jobs/:id/wait | Wait for job |
Webhooks Management Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/webhooks | List webhooks |
| GET | /api/webhooks/:id | Get webhook |
| PUT | /api/webhooks/:id/enable | Enable webhook |
| PUT | /api/webhooks/:id/disable | Disable webhook |
| DELETE | /api/webhooks/:id | Delete webhook |
| POST | /api/webhooks/:id/regenerate-secret | Regenerate secret |
Payments (x402) Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/payments/status | Payment configuration status |
| GET | /api/payments/history | Payment history |
| GET | /api/payments/balance/:network | Network balance |
| GET | /api/payments/address/:network | Wallet address |
Embeddings Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/embeddings/embed | Embed single text |
| POST | /api/embeddings/embed-batch | Embed multiple texts |
| POST | /api/embeddings/similarity | Cosine similarity |
| POST | /api/embeddings/search | Semantic search |
| POST | /api/embeddings/cache/clear | Clear cache |
Cron Service Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/cron/status | Service status |
| GET | /api/cron/jobs | List jobs |
| GET | /api/cron/jobs/:id | Get job |
| POST | /api/cron/jobs | Create job |
| PATCH | /api/cron/jobs/:id | Update job |
| DELETE | /api/cron/jobs/:id | Remove job |
| POST | /api/cron/jobs/:id/run | Run job immediately |
Position Manager Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/positions/managed | List managed positions + stats |
| GET | /api/positions/managed/:id | Get position |
| GET | /api/positions/managed/by-platform/:platform | Positions by platform |
| POST | /api/positions/managed | Create/update position |
| POST | /api/positions/managed/:id/close | Close position |
| POST | /api/positions/managed/:id/stop-loss | Set stop-loss |
| POST | /api/positions/managed/:id/take-profit | Set take-profit |
| DELETE | /api/positions/managed/:id/stop-loss | Remove stop-loss |
| DELETE | /api/positions/managed/:id/take-profit | Remove take-profit |
| PUT | /api/positions/managed/:id/price | Update price |
| PUT | /api/positions/managed/prices | Batch update prices |
| POST | /api/positions/managed/start | Start monitoring |
| POST | /api/positions/managed/stop | Stop monitoring |
Clodds Compute API
The Compute API allows agents to pay for compute resources with USDC. No API keys needed - just a wallet.
Base URL
https://api.cloddsbot.com
Authentication
No API keys required. Agents authenticate by:
- Depositing USDC to the treasury wallet on any supported network
- Including payment proof in requests
Treasury wallet: Set via CLODDS_TREASURY_WALLET env var on the server.
Supported networks: Base, Ethereum, Polygon (USDC)
Rate Limiting
- Per-wallet: 60 requests/minute
- Per-IP: 100 requests/minute
Rate limit headers are included in responses:
X-RateLimit-Remaining: Remaining requests in windowRetry-After: Seconds to wait (when rate limited)
Endpoints
GET /v1/health
Health check and service info.
Response:
{
"status": "ok",
"service": "clodds-compute",
"version": "v1",
"uptime": 123456,
"activeJobs": 2
}
GET /v1/pricing
Get pricing for all compute services.
Response:
{
"llm": {
"service": "llm",
"basePrice": 0,
"unit": "token",
"pricePerUnit": 0.000003,
"minCharge": 0.001,
"maxCharge": 10
},
"code": {
"service": "code",
"basePrice": 0.01,
"unit": "second",
"pricePerUnit": 0.001,
"minCharge": 0.01,
"maxCharge": 1
},
"web": {
"service": "web",
"basePrice": 0.005,
"unit": "request",
"pricePerUnit": 0.005,
"minCharge": 0.005,
"maxCharge": 0.1
},
"trade": {
"service": "trade",
"basePrice": 0.01,
"unit": "call",
"pricePerUnit": 0.01,
"minCharge": 0.01,
"maxCharge": 0.5
},
"data": {
"service": "data",
"basePrice": 0.001,
"unit": "request",
"pricePerUnit": 0.001,
"minCharge": 0.001,
"maxCharge": 0.1
},
"storage": {
"service": "storage",
"basePrice": 0,
"unit": "mb",
"pricePerUnit": 0.0001,
"minCharge": 0.001,
"maxCharge": 1
},
"gpu": {
"service": "gpu",
"basePrice": 0,
"unit": "second",
"pricePerUnit": 0.01,
"minCharge": 0.1,
"maxCharge": 100
},
"ml": {
"service": "ml",
"basePrice": 0.01,
"unit": "request",
"pricePerUnit": 0.01,
"minCharge": 0.01,
"maxCharge": 1
}
}
GET /v1/metrics
Get API metrics and statistics.
Response:
{
"uptime": 123456,
"totalRequests": 1500,
"totalRevenue": 45.50,
"activeJobs": 2,
"jobsByStatus": {
"pending": 1,
"processing": 1,
"completed": 1450,
"failed": 48
},
"requestsByService": {
"llm": 1200,
"code": 200,
"web": 100
}
}
GET /v1/balance/:wallet
Check wallet balance.
Response:
{
"wallet": "0x...",
"available": 10.50,
"pending": 0.25,
"totalDeposited": 15.00,
"totalSpent": 4.25
}
POST /v1/deposit
Deposit credits to a wallet.
Request body:
{
"wallet": "0x...",
"paymentProof": {
"txHash": "0x...",
"network": "base",
"amountUsd": 10.00,
"token": "USDC",
"timestamp": 1706500000000
}
}
Response:
{
"success": true,
"credits": 10.00,
"txHash": "0x..."
}
GET /v1/usage/:wallet
Get usage statistics for a wallet.
Query parameters:
period(optional):day,week,month, orall(default:all)
Response:
{
"wallet": "0x...",
"period": "week",
"byService": {
"llm": {
"requests": 50,
"cost": 2.50,
"avgDuration": 1500
},
"code": {
"requests": 10,
"cost": 0.50,
"avgDuration": 3000
}
},
"totalCost": 3.00,
"totalRequests": 60
}
GET /v1/jobs/:wallet
List jobs for a wallet.
Query parameters:
limit(optional): Max results (default: 50, max: 100)
Response:
{
"jobs": [
{
"id": "req_123",
"jobId": "job_456",
"service": "llm",
"status": "completed",
"cost": 0.05,
"timestamp": 1706500000000
}
],
"count": 1
}
GET /v1/job/:jobId
Get status of an async compute job.
Headers:
X-Wallet-Address(optional): Wallet address for ownership verification
Response:
{
"id": "req_123",
"jobId": "job_456",
"service": "llm",
"status": "completed",
"result": {
"content": "The weather is sunny.",
"model": "claude-opus-4-6",
"usage": { "inputTokens": 10, "outputTokens": 5 },
"stopReason": "end_turn"
},
"cost": 0.05,
"usage": {
"units": 1500,
"unitType": "token",
"durationMs": 2300,
"breakdown": {
"base": 0,
"usage": 0.0045,
"total": 0.0045
}
},
"timestamp": 1706500000000
}
Status values: pending, processing, completed, failed
DELETE /v1/job/:jobId
Cancel a pending job and refund the reserved balance.
Headers:
X-Wallet-Address(required): Wallet address for ownership verification
Response:
{
"success": true,
"jobId": "job_456"
}
Note: Only pending jobs can be cancelled. Processing/completed jobs cannot be cancelled.
POST /v1/compute/:service
Submit a compute request. Replace :service with: llm, code, web, trade, data, storage, gpu, ml, or security.
Request body:
{
"wallet": "0x...",
"payload": { ... },
"paymentProof": {
"txHash": "0x...",
"network": "base",
"amountUsd": 10.00,
"token": "USDC",
"timestamp": 1706500000000
},
"callbackUrl": "https://your-server.com/webhook"
}
Response:
{
"id": "req_123",
"jobId": "job_456",
"service": "llm",
"status": "pending",
"cost": 0.05,
"timestamp": 1706500000000
}
Service Payloads
LLM Service
{
"wallet": "0x...",
"payload": {
"model": "claude-opus-4-6",
"messages": [
{ "role": "user", "content": "What's the weather?" }
],
"system": "You are a helpful assistant",
"maxTokens": 1000,
"temperature": 0.7
}
}
Available models:
claude-opus-4-6(latest, most capable)claude-sonnet-4-5-20250929claude-haiku-4-5-20251001gpt-4ogpt-4o-minillama-3.1-70bllama-3.1-8bmixtral-8x7b
Code Execution Service
{
"wallet": "0x...",
"payload": {
"language": "python",
"code": "print('Hello World')",
"stdin": "",
"timeout": 30000,
"memoryMb": 256
}
}
Supported languages: python, javascript, typescript, rust, go, bash
Web Scraping Service
{
"wallet": "0x...",
"payload": {
"url": "https://example.com",
"method": "GET",
"headers": {},
"javascript": false,
"extract": {
"title": "title",
"heading": "h1"
}
}
}
Data Service
{
"wallet": "0x...",
"payload": {
"type": "price",
"query": {
"asset": "bitcoin"
}
}
}
Data types: price, orderbook, candles, trades, markets, positions, balance, news, sentiment, percolator_state
Trade Service
{
"wallet": "0x...",
"payload": {
"platform": "polymarket",
"action": "buy",
"marketId": "0x...",
"size": 100,
"price": 0.55
}
}
Supported platforms: polymarket, kalshi, hyperliquid, binance, bybit, mexc, jupiter, raydium, orca, percolator
Percolator-specific payload:
{
"wallet": "0x...",
"payload": {
"platform": "percolator",
"action": "long",
"size": 100,
"slabAddress": "A7wQtRT9DhFqYho8wTVqQCDc7kYPTUXGPATiyVbZKVFs"
}
}
Security Service
Scan code or addresses for security risks.
{
"wallet": "0x...",
"payload": {
"type": "code_scan",
"code": "const x = eval(input);"
}
}
Security types: code_scan, address_check, token_audit, tx_validate
Token audit payload:
{
"wallet": "0x...",
"payload": {
"type": "token_audit",
"address": "0x...",
"chain": "ethereum"
}
}
Storage Service
{
"wallet": "0x...",
"payload": {
"operation": "put",
"key": "my-file.txt",
"content": "Hello World",
"contentType": "text/plain",
"ttl": 3600
}
}
Operations: put, get, delete, list
Payment Flow
- Deposit USDC to the treasury wallet on Base network
- Include payment proof in your first request:
{ "paymentProof": { "txHash": "0x...", "network": "base", "amountUsd": 10.00, "token": "USDC", "timestamp": 1706500000000 } } - API verifies on-chain and credits your balance
- Subsequent requests just need your wallet address - balance is tracked server-side
Error Responses
{
"id": "req_123",
"jobId": "job_456",
"service": "llm",
"status": "failed",
"error": "Insufficient balance. Need $0.05, have $0.00",
"cost": 0,
"timestamp": 1706500000000
}
Webhooks
If you provide a callbackUrl, the API will POST results when jobs complete:
{
"id": "req_123",
"jobId": "job_456",
"service": "llm",
"status": "completed",
"result": { ... },
"cost": 0.05,
"timestamp": 1706500000000
}
The webhook includes an X-Clodds-Signature header (HMAC-SHA256) for verification.
Streaming LLM Endpoint
POST /v1/stream/llm
Stream LLM responses via Server-Sent Events (SSE). This endpoint streams text chunks in real-time as the model generates them.
Request body:
{
"wallet": "0x...",
"payload": {
"model": "claude-opus-4-6",
"messages": [
{ "role": "user", "content": "Write a poem about coding" }
],
"system": "You are a creative writer",
"maxTokens": 1000,
"temperature": 0.7
}
}
Response: Server-Sent Events stream
data: {"type": "start", "requestId": "req_123"}
data: {"type": "text", "text": "In "}
data: {"type": "text", "text": "the "}
data: {"type": "text", "text": "realm "}
data: {"type": "text", "text": "of "}
data: {"type": "text", "text": "code..."}
data: {"type": "usage", "usage": {"inputTokens": 25, "outputTokens": 150}}
data: {"type": "done", "response": {"content": "In the realm of code...", "model": "claude-opus-4-6", "usage": {"inputTokens": 25, "outputTokens": 150}, "stopReason": "end_turn"}}
Event types:
start: Stream initiated, includes requestIdtext: Text chunk from the modelusage: Token usage statisticserror: Error occurreddone: Stream complete, includes full response
JavaScript example:
const response = await fetch('https://api.cloddsbot.com/v1/stream/llm', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
wallet: '0x...',
payload: {
model: 'claude-opus-4-6',
messages: [{ role: 'user', content: 'Hello' }]
}
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
if (data.type === 'text') {
process.stdout.write(data.text);
}
}
}
}
Supported streaming models:
- All Claude models (via Anthropic streaming API)
- All GPT models (via OpenAI streaming API)
- All Together models (Llama, Mixtral)