Every tool is a GET endpoint under https://api.fundalyze.ai/api/public/v1, with the tool's parameters as the query string and your API key as a bearer token. The examples use fetch, built into Node.js 18 and later, Deno, Bun and serverless runtimes.

Keep the key on the serverLink to this section

Call the API from server code (a script, an API route, a serverless function), never from JavaScript that runs in your users' browsers: anything sent to a browser can be read, and a key that leaks spends your calls. Put the key in an environment variable:

export FUNDALYZE_API_KEY="fdz_live_YOUR_KEY"

Your first callLink to this section

const params = new URLSearchParams({ ticker: 'NVDA', limit: '5' })

const response = await fetch(`https://api.fundalyze.ai/api/public/v1/get_insider_trades?${params}`, {
  headers: { Authorization: `Bearer ${process.env.FUNDALYZE_API_KEY}` },
})
const answer = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${answer.detail}`)

console.log(answer.text) // the compact table an assistant would read
for (const trade of answer.data.trades) {
  console.log(trade.filed_date, trade.owner, trade.code, trade.shares, trade.value_usd)
}
console.log('Calls left today:', response.headers.get('X-Quota-Remaining'))

Run it with node first-call.mjs. A list parameter (such as metrics on get_financials) can be repeated with params.append('metrics', 'revenue') or sent comma-separated; the API accepts both.

A small clientLink to this section

Fundalyze runs one call at a time per key, so await each call before the next instead of firing them together with Promise.all. This helper retries while the key is busy with an earlier call and throws the API's own message otherwise:

const BASE = 'https://api.fundalyze.ai/api/public/v1'

export async function call(tool, params = {}) {
  const query = new URLSearchParams()
  for (const [key, value] of Object.entries(params)) {
    for (const v of [value].flat()) query.append(key, String(v))
  }
  for (let attempt = 0; attempt < 4; attempt++) {
    const response = await fetch(`${BASE}/${tool}?${query}`, {
      headers: { Authorization: `Bearer ${process.env.FUNDALYZE_API_KEY}` },
    })
    const body = await response.json().catch(() => ({ detail: response.statusText }))
    if (response.ok) return body
    const busy = response.status === 429 && String(body.detail).includes('still running')
    if (busy && attempt < 3) {
      await new Promise((resolve) => setTimeout(resolve, 1000 * (attempt + 1)))
      continue
    }
    throw new Error(`${response.status}: ${body.detail}`)
  }
}

// Example: three tickers, one after another.
for (const ticker of ['AAPL', 'MSFT', 'GOOGL']) {
  const { data } = await call('get_financials', { ticker, metrics: ['revenue', 'net_margin'], years: 3 })
  console.log(ticker, data.periods, data.metrics.map((m) => [m.key, m.values]))
}

TypeScriptLink to this section

The answer's shape is the same for every tool; data differs per tool and is described field by field on each reference page:

interface FundalyzeAnswer<Data> {
  text: string // compact table for a language model
  data: Data // the same content as JSON
  link: string | null // the fundalyze.ai page to check it on
}

To generate a typed client instead, point your generator at the OpenAPI document.

Next: Errors, or a worked task in Recipes.

This page as Markdown, for language models and scripts: /developers/md/quickstart/javascript