Ask several frontier models the same question and get one synthesized answer. Choose a preset council — fast (3 quick models), balanced (3 strong models with a peer-refine round), or deep (5 models plus refine) — or supply your own set of 2–8 models. A chairman model merges the responses into a single consensus with a confidence score and any points of dissent, and each member’s individual answer is returned alongside. Price scales with the council size and answer length, and is quoted up front in the 402. Models auto-resolve to their latest available version; any unavailable model simply drops out (at least 2 are needed).
/api/ai/councilPAYMENT-SIGNATURE.ai.council asks the same question to several frontier models at once, optionally lets them refine against each other, then has a chairman model synthesize one consensus answer with a confidence score and any points of dissent — and returns each model’s individual answer alongside.
Pick a preset council — fast (3 quick models, single pass), balanced (3 strong models with a peer-refine round), or deep (5 models plus refine) — or pass your own set of 2–8 models. Models route through a single gateway and auto-resolve to their latest available version, so the council stays current; if a model is temporarily unavailable it simply drops out (at least two are required).
Pricing is dynamic: because every model and answer length costs differently, the exact price is computed per request and quoted in the 402 challenge before you pay. For the live council line-ups, the full list of models you can pass, and current example prices, call GET /api/ai/council/menu (free).
| Name | Type | Description |
|---|---|---|
promptrequired | string | The question to put to the council. min 1 chars · max 12000 chars |
mode | string | Preset council. Default balanced. Ignored if `models` is given. one of: fast | balanced | deep |
models | array | Custom council of 2–8 gateway model ids, e.g. ["openai/gpt-5","anthropic/claude-opus","google/gemini-3-pro"] (overrides `mode`). Full selectable list + live prices: GET /api/ai/council/menu. |
maxTokens | integer | Max output tokens per model. Default 640. min 128 · max 4096 |
# 1. Probe the endpoint with no auth — receive 402 with PaymentRequirements
curl -sS -X POST 'https://2s.io/api/ai/council' \
-H 'Content-Type: application/json' \
-d '{"prompt":"example","mode":"fast","models":["example"],"maxTokens":128}'
# 2. Sign the EIP-3009 transferWithAuthorization for the advertised price +
# payTo from the 402 envelope, then retry with PAYMENT-SIGNATURE:
curl -sS -X POST 'https://2s.io/api/ai/council' \
-H 'Content-Type: application/json' \
-H 'PAYMENT-SIGNATURE: <base64-json-payload>' \
-d '{"prompt":"example","mode":"fast","models":["example"],"maxTokens":128}'
# Or just use the canonical runner — it handles the whole loop:
# EVM_PRIVATE_KEY=0x... node --env-file=.env.local \
# --experimental-strip-types scripts/x402-pay.ts \
# 'https://2s.io/api/ai/council'import { TwoS } from '@2sio/sdk'
const client = new TwoS({
privateKey: process.env.EVM_PRIVATE_KEY as `0x${string}`,
})
const result = await client.ai.council({
"prompt": "example",
"mode": "fast",
"models": [
"example"
],
"maxTokens": 128
})
console.log('endpoint:', result.endpoint)
console.log('cost:', result.costUsd, 'USDC')
console.log('tx:', result.settlement?.txHash)
console.log('data:', result.data)import os
from twosio import TwoS
client = TwoS(private_key=os.environ["EVM_PRIVATE_KEY"])
result = client.ai.council(prompt="example", mode="fast", models=["example"], maxTokens=128)
print("endpoint:", result.endpoint)
print("cost:", result.cost_usd, "USDC")
print("tx:", (result.settlement or {}).get("tx_hash"))
print("data:", result.data)// 1. Add @2sio/mcp to your MCP host config (Claude Desktop example below).
// EVM_PRIVATE_KEY funds x402 payments per call.
// claude_desktop_config.json
{
"mcpServers": {
"2sio": {
"command": "npx",
"args": ["-y", "@2sio/mcp"],
"env": { "EVM_PRIVATE_KEY": "0x..." }
}
}
}
// 2. Once the server is running, agents call this tool via standard MCP:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "ai.council",
"arguments": {
"prompt": "example",
"mode": "fast",
"models": [
"example"
],
"maxTokens": 128
}
}
}| Field | Type | Description |
|---|---|---|
ok | boolean | one of: true |
items | array | |
total | integer | Total matching rows upstream; null when unknown. |
source | object | |
meta | object |
{
"ok": true,
"items": [
{
"consensus": "example",
"confidence": 1,
"agreement": "example",
"dissent": [
"example"
],
"models": [
{
"model": "example",
"answered": false,
"answer": "example"
}
]
}
],
"total": 1,
"source": {
"provider": "example",
"url": "example",
"license": "example"
},
"meta": {
"mode": "example",
"chairman": "example",
"modelCount": 1,
"answered": 1
}
}