Intelligence API
Ship market intelligence in your own product — trade angles, timely signals, hero briefs, and optional deep links — through one versioned HTTP feed. Production runs manifest v7 with a single primary endpoint; specialized routes are thin views over the same assembler.
At a glance
| Base URL | https://app.torque.fi/api/v1 |
| Primary route | GET /api/v1/intelligence/feed |
| Auth | Authorization: Bearer sk_live_… (business API key) |
| Manifest | 7 — probe GET /api/v1/capabilities |
| Canonical item | IntelligenceItemV1 |
Who this is for
Partners, personal dashboards, fintech shells, and notification products that want Torque desk synthesis and live market signals without re-implementing the intelligence pipeline. You call HTTP; Torque runs ingestion, classification, dedupe, and ranking server-side.
This API is read-only intelligence. On-chain actions (swap, transfer, lend) use Actions API routes under /api/v1/actions/**. Conversational flows use Assistant API with the same business key.
Get started
- Create or open a Torque Business account at app.torque.fi.
- Go to Business Settings → API Integration and copy your
sk_live_…key. Never expose this in browser bundles — proxy from your backend. - Probe capabilities (no auth required) to confirm manifest and primary route.
- Fetch the feed with your key. Pass an optional
walletAddresswhen you want personalized trade angles and stored outlook context.
curl -sS "https://app.torque.fi/api/v1/capabilities" \
| jq '.manifestVersion, .intelligence.primary'
# expect: 7 and "/api/v1/intelligence/feed"export TORQUE_KEY="sk_live_…"
export WALLET="0x…" # optional — personalization
curl -sS "https://app.torque.fi/api/v1/intelligence/feed?walletAddress=$WALLET&chainId=8453&includeBrief=1" \
-H "Authorization: Bearer $TORQUE_KEY" \
| jq '.meta.manifestVersion, .meta.route, (.items | length), .brief.summary'How it works
Torque ingests tape, social, desk, and third-party sources into an internal bundle. The v7 integrator layer projects that bundle into a stable JSON shape — you never consume the raw bundle.
Integrator rule: call the v1 feed (or a specialized view). Do not merge separate news APIs for market context — the feed already dedupes overlapping catalysts across signals and angles.
Authentication
Intelligence routes require a business API key — the same credential used for Checkout and server-side assistant chat.
Authorization: Bearer sk_live_…| Credential | Identifies | Routes |
|---|---|---|
| sk_live_… | Your business / integrator | /api/v1/intelligence/**, assistant/chat (server) |
| walletAddress (query) | End-user context for personalization | Optional on feed, trade-angles, brief, market-outlook |
| smart_wallet JWT | Signed-in Torque user | /api/v1/actions/** (not intelligence reads) |
A 401 without a Bearer token means the route exists but auth is missing — that is the expected probe response for unauthenticated curl.
Discovery
GET /api/v1/capabilities returns a machine-readable manifest. Check manifestVersion and intelligence.primary before wiring client logic.
{
"manifestVersion": 7,
"intelligence": {
"status": "available",
"schema": "IntelligenceItemV1",
"auth": "business_api_key",
"primary": "/api/v1/intelligence/feed",
"integrationProfiles": {
"homeFeed": {
"routes": ["/api/v1/intelligence/feed"],
"auth": ["businessApiKey"],
"context": ["walletAddress", "chainId"]
},
"conversational": {
"routes": ["/api/v1/assistant/chat"],
"auth": ["businessApiKey"],
"context": ["walletAddress"]
},
"actionable": {
"routes": ["/api/v1/actions/**"],
"auth": ["smartWalletJwt"]
}
},
"compatibility": {
"legacyTier": {
"deprecatedForIntegrators": true,
"routes": ["/api/home/signals", "/api/home/happening-now"],
"migrateTo": "/api/v1/intelligence/feed"
}
}
}
}Primary feed
GET https://app.torque.fi/api/v1/intelligence/feed
Authorization: Bearer sk_live_…Query parameters
| Param | Default | Description |
|---|---|---|
| walletAddress | — | Personalize trade angles and outlook context |
| chainId | 8453 (Base) | Chain for action deep links in items |
| lanes | all | Comma-separated: timely, desk, outlook |
| kinds | signal,angle | Comma-separated: signal, angle, brief, outlook |
| limit | 12 (max 24) | Max items in flat items[] |
| includeBrief | 0 | Set 1 to include brief object |
| force | 0 | Set 1 to force live angle reroll (cooldown applies) |
Response shape
{
"meta": {
"manifestVersion": 7,
"generatedAtMs": 1710000000000,
"bundleIngestedAtMs": 1710000004500,
"personalized": true,
"walletAddress": "0x892e…",
"chainId": 8453,
"resolution": {
"angles": { "tier": "pool", "ageMs": 120000 },
"signals": { "tier": "live", "bundleAgeMs": 45000 }
},
"dedupedCount": 2
},
"brief": { "id": "…", "kind": "brief", "title": "…", "summary": "…", "symbols": ["ETH"] },
"lanes": {
"timely": { "id": "timely", "label": "Happening now", "items": [/* signal */] },
"desk": { "id": "desk", "label": "Trade angles", "items": [/* angle */] }
},
"items": [/* flat, deduped, server-ranked list */]
}Data model — IntelligenceItemV1
Every v7 surface returns the same item shape. Render one list or carousel component; branch on kind for labels and styling. Ignore unknown kinds forward-compatibly.
| kind | Meaning | Typical lane |
|---|---|---|
| signal | Proactive / happening-now market event | timely |
| angle | Desk trade read with bias and levels | desk |
| brief | Hero one-liner for home / notification surfaces | — (top-level brief field) |
| outlook | Stored market outlook synthesis per wallet | outlook |
{
"id": "desk_ETH_watch_gmq2sjj9i",
"kind": "angle",
"title": "ETH tokenization megatrend, short squeeze potential",
"summary": "Ethereum looks constructive toward $1,600…",
"horizon": "swing",
"symbols": ["ETH"],
"bias": "Watch",
"relevanceScore": 4,
"levels": { "last": 1554.71, "invalidation": 1530, "target": 1600 },
"source": { "type": "desk", "label": "Torque desk synthesis" },
"actions": [
{ "label": "Long ETH", "href": "/trade/futures?symbol=ETH&side=long", "chainId": 999, "iconSymbol": "ETH" }
],
"dedupeKey": "eth-tokenization-megatrend",
"ingestedAtMs": 1710000000000,
"resolution": { "tier": "pool", "ageMs": 312564 }
}summary is always the display body (formerly deskRead or description). dedupeKey collapses duplicate catalysts across signals and angles server-side — do not re-implement client merge logic on v7.
Enriched action tiles
Each feed item can include actions[] — deep links for lend, borrow, trade, and perp tiles. Intelligence gives context + links; rates on feed actions come from outlook/completion rules when present, not always live catalog APY. For structured rate tables, use the Opportunities API.
| Field | Example | Use |
|---|---|---|
| label | "Lend USD" | Primary tile title |
| subtitle | "Earn 23.45% APY on USD via Aave." | Secondary line |
| href | /lend?supply=usd | Torque app path |
| torqueUrl | https://app.torque.fi/lend?… | Absolute link for partners |
| apyPercent / aprPercent | 23.45 / 3.35 | Supply yield / borrow rate |
| opportunityType | lend | borrow | trade | perp | other | Tile category |
| protocol | "Aave" | Venue label |
| idleUsd / estimatedAnnualUsd | — | Personalized yield only |
SDK methods
| Endpoint | torque-node / torque-intelligence | Returns |
|---|---|---|
| GET …/intelligence/feed | getFeed() | Signals, angles, brief, lanes |
| GET …/intelligence/trade-angles | getTradeAngles() | Desk trade angles |
| GET …/intelligence/happening-now | getHappeningNow() | Timely macro/crypto signals |
| GET …/intelligence/brief | — | Single brief item |
| GET …/intelligence/market-outlook | — | Stored outlook for wallet |
Lanes vs flat items
Single carousel
Render items[] only. Torque has already deduped and ranked the mixed feed.
Two-section layout
Use lanes.desk for trade angles and lanes.timely for happening now — same items, pre-partitioned.
Pass includeBrief=1 and render brief.summary as a hero line above the carousel (home dashboards, morning notifications).
Specialized views
These routes are thin wrappers over the same assembler. Prefer the primary feed for new integrations; keep views only when you need a smaller payload or legacy response keys.
| Route | Equivalent feed filter | Response |
|---|---|---|
| GET …/trade-angles | kinds=angle, lanes=desk | { ideas: IntelligenceItemV1[], meta } |
| GET …/happening-now | kinds=signal, lanes=timely | { items, ingestedAtMs, meta } |
| GET …/brief | includeBrief=1 | { brief: IntelligenceItemV1 } |
| GET …/market-outlook | kinds=outlook, wallet required | { item, meta } — 404 when none stored |
Recommended integration pattern (BFF)
Never ship sk_live_… to browsers. Proxy from your backend (Next.js route, Cloudflare Worker, etc.) and attach the key server-side. Cache privately (~60s) per user session.
// app/api/intelligence/feed/route.ts (your app)
import { NextRequest, NextResponse } from "next/server"
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url)
const params = new URLSearchParams({
chainId: searchParams.get("chainId") ?? "8453",
includeBrief: "1",
})
const wallet = searchParams.get("walletAddress") ?? process.env.TORQUE_WALLET_ADDRESS
if (wallet) params.set("walletAddress", wallet)
const res = await fetch(
`https://app.torque.fi/api/v1/intelligence/feed?${params}`,
{ headers: { Authorization: `Bearer ${process.env.TORQUE_API_KEY}` } }
)
const data = await res.json()
return NextResponse.json(data, {
status: res.status,
headers: { "Cache-Control": "private, max-age=60" },
})
}// Client — calls YOUR BFF, not Torque directly
const res = await fetch("/api/intelligence/feed?chainId=8453")
const feed = await res.json()
const desk = feed.lanes?.desk?.items ?? feed.items.filter((i) => i.kind === "angle")
const timely = feed.lanes?.timely?.items ?? feed.items.filter((i) => i.kind === "signal")
const hero = feed.brief?.summaryErrors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED / INVALID_API_KEY | Missing or invalid business key |
| 429 | COOLDOWN | force=1 within reroll cooldown — body includes retryAfterMs |
| 503 | INTELLIGENCE_UNAVAILABLE | Bundle / orchestrator temporarily unavailable |
Migration from legacy routes
If you integrated before v7 using separate calls or legacy in-app routes, migrate as follows:
| Before | After (v7) |
|---|---|
| /api/home/signals | /api/v1/intelligence/feed?kinds=angle |
| /api/home/happening-now | /api/v1/intelligence/feed?kinds=signal |
| Two parallel fetches + client merge | One feed call — server dedupes |
| ideas[].deskRead | items[].summary |
Smoke tests
BASE="https://app.torque.fi"
KEY="sk_live_…"
WALLET="0x…"
# 1. Capabilities
curl -sf "$BASE/api/v1/capabilities" | jq -e '.manifestVersion >= 7'
curl -sf "$BASE/api/v1/capabilities" | jq -e '.intelligence.primary == "/api/v1/intelligence/feed"'
# 2. Feed shape
curl -sf -H "Authorization: Bearer $KEY" \
"$BASE/api/v1/intelligence/feed?walletAddress=$WALLET&includeBrief=1" \
| jq -e '.meta.manifestVersion == 7 and .items[0].summary != null'
# 3. Route exists without key (401 expected)
curl -s -o /dev/null -w "%{http_code}" "$BASE/api/v1/intelligence/feed" | grep -q 401See also
- Opportunities API — structured yield and lending rates for "Earn X%" / "Borrow at X%" tiles
- Assistant API — conversational layer with the same business key
- Platform SDK — torque-node and torque-intelligence clients
- Live capabilities JSON