Files
alsk1992andClaude Opus 4.6 5ec72d8f39 Restore payments, credentials, bittensor, API docs to public repo
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>
2026-02-10 02:41:41 +00:00

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_TOKEN and 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-signature or x-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 success
  • 401 for missing/invalid signatures
  • 404 for unknown webhook paths
  • 429 if 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 404 if that platform handler is not configured.

GET /market-index/search

Search the market index (requires marketIndex.enabled).

Query parameters:

  • q (string, required): search text
  • platform (string, optional): polymarket|kalshi|manifold|metaculus
  • limit (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 outcome
  • startTime (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 ID
  • interval (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 outcome
  • startTime (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|sticker
  • url or data (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=timestamp for 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:

  • q or query (string, required): search text
  • platform (string, optional): polymarket|kalshi|manifold
  • limit (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 list
  • limit (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 webhook
  • POST /webhook/discord - Discord Interactions endpoint
  • POST /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:

  1. Depositing USDC to the treasury wallet on any supported network
  2. 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 window
  • Retry-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, or all (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-20250929
  • claude-haiku-4-5-20251001
  • gpt-4o
  • gpt-4o-mini
  • llama-3.1-70b
  • llama-3.1-8b
  • mixtral-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

  1. Deposit USDC to the treasury wallet on Base network
  2. Include payment proof in your first request:
    {
      "paymentProof": {
        "txHash": "0x...",
        "network": "base",
        "amountUsd": 10.00,
        "token": "USDC",
        "timestamp": 1706500000000
      }
    }
    
  3. API verifies on-chain and credits your balance
  4. 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 requestId
  • text: Text chunk from the model
  • usage: Token usage statistics
  • error: Error occurred
  • done: 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)