Financial data API for AI agents
Most market-data APIs were designed for human dashboards: one ticker per call, REST endpoints scoped to a single domain (quotes, fundamentals, filings, news), and monthly subscriptions paid by a person with a credit card. Agents work differently. A single research turn often needs five tickers across four domains, and the agent itself — not a human — is paying. Jintel is shaped around those constraints.
What changes when the caller is a model
There are three shifts that matter:
-
Typed schemas beat freeform JSON. Agents call tools through structured schemas (OpenAI function calling, Anthropic tool use, MCP). A typed GraphQL schema means the model knows exactly which fields exist, which are nullable, and what shape the response will take — without scraping a Markdown reference page. The full Jintel schema is discoverable via standard GraphQL introspection and the agent-friendly tool catalog advertised on
/openapi.json. -
Fan-out beats N+1. A "should I buy NVDA" prompt expands into roughly: latest quote, last 30 days of price history, fundamentals, analyst consensus, recent news, technical indicators, and any insider trades. That's six REST calls per ticker on a typical vendor — six round trips, six rate-limit slots, six places where one call can fail and break the chain. With Jintel, every one of those is a sub-graph on
Entityand resolves in a single round trip via Mercurius loaders. See the sub-graphs guide for the full list. -
Per-query pricing beats subscription tiers. Agents that call APIs from someone else's wallet (or their own budget) need to know the cost of a request before they make it. Jintel exposes a free
estimateCredits(query, variables)lookahead and prices eachPOST /api/graphqlcall deterministically based on the GraphQL AST. On the x402 rail, the agent's wallet signs a USDC payment per request — no signup, no API key, no monthly contract.
Schema-shape for batched research
The two queries you'll use most are quotes(tickers: […]) and entitiesByTickers(tickers: […]). Both accept a list and fan out internally. quotes is the cheapest path when all you need is price + change. entitiesByTickers returns full Entity objects whose nested sub-graphs (market, news, analyst, technicals, regulatory, insiderTrades, earnings, ownership, ...) lazy-resolve only what you select. Selecting nothing costs nothing; selecting six sub-graphs across five tickers is one HTTP call.
Crypto tickers route to CoinGecko / Binance automatically — quotes(tickers: ["AAPL", "BTC"]) is valid. Equity tickers route to Yahoo Finance. The mixing is transparent at the schema level.
A research-agent fan-out
Here's the shape of a single GraphQL request that gives an agent enough context to write a one-paragraph note on each ticker:
query AgentResearch($tickers: [String!]!) {
entitiesByTickers(tickers: $tickers) {
name
tickers
market {
quote { price changePercent volume marketCap }
fundamentals {
peRatio forwardPE pegRatio priceToSales
revenueGrowth earningsGrowth grossMargin operatingMargin
sector industry
}
}
analyst {
recommendation targetMean numberOfAnalysts
}
technicals { rsi ema50 sma200 macd { histogram } }
news(filter: { limit: 5, sort: DESC }) {
title date source sentimentScore link
}
insiderTrades(filter: { limit: 5 }) {
reporterName officerTitle transactionDate
acquiredDisposed shares pricePerShare transactionValue
}
}
}
Run it once with { "tickers": ["NVDA", "AMD", "INTC"] } and you get five domains of data on three tickers in a single response, billed against a single per-query x402 quote (or a single deduction from your monthly plan credits).
- curl
- TypeScript SDK
curl https://api.jintel.ai/api/graphql \
-H "Authorization: Bearer $JINTEL_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"query": "query($t:[String!]!){entitiesByTickers(tickers:$t){name tickers market{quote{price changePercent} fundamentals{peRatio sector}} analyst{recommendation targetMean} news(filter:{limit:3}){title date sentimentScore}}}",
"variables": { "t": ["NVDA", "AMD", "INTC"] }
}
JSON
import { JintelClient } from "@yojinhq/jintel-client";
const jintel = new JintelClient({ apiKey: process.env.JINTEL_API_KEY });
const { data } = await jintel.request(`
query($t:[String!]!) {
entitiesByTickers(tickers: $t) {
name tickers
market { quote { price changePercent } fundamentals { peRatio sector } }
analyst { recommendation targetMean }
news(filter: { limit: 3 }) { title date sentimentScore }
}
}
`, { t: ["NVDA", "AMD", "INTC"] });
Where to go next
- Sub-graphs — full list of nested fields available on
EntityandMarketQuote. - Batching — how Mercurius loaders deduplicate fan-out and why a single request beats N requests.
- Agents & x402 — pay-per-query with an agent wallet, no signup.
- MCP server — drop Jintel into Claude Desktop or any MCP-aware client.