TorqueTorque

Search docs

Search Torque documentation pages and sections

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 URLhttps://app.torque.fi/api/v1
Primary routeGET /api/v1/intelligence/feed
AuthAuthorization: Bearer sk_live_… (business API key)
Manifest7 — probe GET /api/v1/capabilities
Canonical itemIntelligenceItemV1

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

  1. Create or open a Torque Business account at app.torque.fi.
  2. Go to Business Settings → API Integration and copy your sk_live_… key. Never expose this in browser bundles — proxy from your backend.
  3. Probe capabilities (no auth required) to confirm manifest and primary route.
  4. Fetch the feed with your key. Pass an optional walletAddress when you want personalized trade angles and stored outlook context.
probe-capabilities.sh
curl -sS "https://app.torque.fi/api/v1/capabilities" \
  | jq '.manifestVersion, .intelligence.primary'
# expect: 7 and "/api/v1/intelligence/feed"
fetch-feed.sh
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.

Tape + insights → intelligence bundle
↓ classify (signals, angles, brief, outlook)
↓ normalize → IntelligenceItemV1[]
↓ dedupe by catalyst key, rank, partition lanes
↓ GET /api/v1/intelligence/feed

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 header
Authorization: Bearer sk_live_…
CredentialIdentifiesRoutes
sk_live_…Your business / integrator/api/v1/intelligence/**, assistant/chat (server)
walletAddress (query)End-user context for personalizationOptional on feed, trade-angles, brief, market-outlook
smart_wallet JWTSigned-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.

capabilities-intelligence.json (excerpt)
{
  "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 /api/v1/intelligence/feed
GET https://app.torque.fi/api/v1/intelligence/feed
Authorization: Bearer sk_live_…

Query parameters

ParamDefaultDescription
walletAddressPersonalize trade angles and outlook context
chainId8453 (Base)Chain for action deep links in items
lanesallComma-separated: timely, desk, outlook
kindssignal,angleComma-separated: signal, angle, brief, outlook
limit12 (max 24)Max items in flat items[]
includeBrief0Set 1 to include brief object
force0Set 1 to force live angle reroll (cooldown applies)

Response shape

IntelligenceFeedResponseV1
{
  "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.

kindMeaningTypical lane
signalProactive / happening-now market eventtimely
angleDesk trade read with bias and levelsdesk
briefHero one-liner for home / notification surfaces— (top-level brief field)
outlookStored market outlook synthesis per walletoutlook
IntelligenceItemV1 (fields)
{
  "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.

FieldExampleUse
label"Lend USD"Primary tile title
subtitle"Earn 23.45% APY on USD via Aave."Secondary line
href/lend?supply=usdTorque app path
torqueUrlhttps://app.torque.fi/lend?…Absolute link for partners
apyPercent / aprPercent23.45 / 3.35Supply yield / borrow rate
opportunityTypelend | borrow | trade | perp | otherTile category
protocol"Aave"Venue label
idleUsd / estimatedAnnualUsdPersonalized yield only

SDK methods

Endpointtorque-node / torque-intelligenceReturns
GET …/intelligence/feedgetFeed()Signals, angles, brief, lanes
GET …/intelligence/trade-anglesgetTradeAngles()Desk trade angles
GET …/intelligence/happening-nowgetHappeningNow()Timely macro/crypto signals
GET …/intelligence/briefSingle brief item
GET …/intelligence/market-outlookStored 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.

RouteEquivalent feed filterResponse
GET …/trade-angleskinds=angle, lanes=desk{ ideas: IntelligenceItemV1[], meta }
GET …/happening-nowkinds=signal, lanes=timely{ items, ingestedAtMs, meta }
GET …/briefincludeBrief=1{ brief: IntelligenceItemV1 }
GET …/market-outlookkinds=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.

nextjs-bff-route.ts
// 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-hook.ts
// 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?.summary

Errors

StatusCodeWhen
401UNAUTHORIZED / INVALID_API_KEYMissing or invalid business key
429COOLDOWNforce=1 within reroll cooldown — body includes retryAfterMs
503INTELLIGENCE_UNAVAILABLEBundle / orchestrator temporarily unavailable

Migration from legacy routes

If you integrated before v7 using separate calls or legacy in-app routes, migrate as follows:

BeforeAfter (v7)
/api/home/signals/api/v1/intelligence/feed?kinds=angle
/api/home/happening-now/api/v1/intelligence/feed?kinds=signal
Two parallel fetches + client mergeOne feed call — server dedupes
ideas[].deskReaditems[].summary

Smoke tests

ci-smoke.sh
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 401

See also

Was this helpful?