Custom integrations

Point your AI agent at Fundra's OpenAPI spec and let it build a fully typed integration against your workspace.

Everything the Fundra API can do is described in a machine-readable OpenAPI 3.1 document, served publicly at:

https://api.fundra.com/v1/openapi.json

No API key is needed to read the spec – only to call the endpoints it describes. That makes it the fastest way to build a custom integration: hand the URL to your coding agent, or generate a typed client from it, and you get exact paths, parameters, response shapes and enums instead of guesswork.

Point your AI agent at it

Claude Code, Cursor, Codex and the rest can all fetch a URL. Give them the spec and the task:

Fetch https://api.fundra.com/v1/openapi.json – it's the OpenAPI spec for the
Fundra API. Using it as the source of truth for paths, parameters and response
shapes, write a script that pulls every portfolio company in fund 1 with its
latest valuation, and writes them to CSV.

Auth: Bearer token in the Authorization header, from the FUNDRA_API_KEY env var.
Generate a typed client rather than hand-writing fetch calls.

Two things make this work well in practice:

  • Tell the agent to generate a client, not to write requests by hand. Generated types fail at compile time when a field doesn't exist; hand-written fetch calls fail silently in production.
  • Tell it to re-read the spec rather than recall the API. The spec is the only current description of the API – anything a model remembers about Fundra is either out of date or invented.

Generate a typed client

TypeScript

openapi-typescript generates types straight from the URL, and openapi-fetch gives you a small typed client over fetch:

npm i -D openapi-typescript
npm i openapi-fetch
npx openapi-typescript https://api.fundra.com/v1/openapi.json -o src/fundra.d.ts
import createClient from "openapi-fetch";
import type { paths } from "./fundra";
 
const fundra = createClient<paths>({
  baseUrl: "https://api.fundra.com/v1",
  headers: { Authorization: `Bearer ${process.env.FUNDRA_API_KEY}` },
});
 
const { data, error } = await fundra.GET("/portfolio-companies", {
  params: { query: { fund_id: "1", limit: 500 } },
});
 
if (error) throw new Error(error.message);
 
for (const pc of data.data) {
  console.log(pc.company.name, pc.investment.fmv, pc.fund.currency);
}

Paths, query parameters and response fields are all checked against the spec, so a typo or a renamed field is a build error rather than a runtime surprise.

@hey-api/openapi-ts is a good alternative if you'd rather have generated SDK methods (listPortfolioCompanies({ ... })) than path strings.

Other languages

Any OpenAPI generator works – the spec is standard 3.1:

LanguageTool
Pythonopenapi-python-client
Go, Java, C#, PHPOpenAPI Generator
RustProgenitor
openapi-python-client generate --url https://api.fundra.com/v1/openapi.json

Authentication

Create a key in Settings → API – admin access required – and send it as a bearer token:

curl https://api.fundra.com/v1/funds \
  -H "Authorization: Bearer fk_your_api_key_here"

A key is scoped to one workspace, so a client built against it reads and writes only that workspace's data. Keep it in an environment variable or a secrets manager; it's shown once and grants the same access as an admin.

Security

Never put Fundra API tokens in front-end apps. We have security policies in place to prevent that, but a willing LLM could try to circumvent it still, which could put your data at risk. Hence, it is very important to make sure that your custom apps have a dedicated backend for querying and manipulating data.

Conventions worth telling your agent

The spec describes the shapes, but not the domain model. These are the things that most often trip up a first integration:

  • Companies are global; portfolio companies are per fund. A company_id identifies the company across your workspace. A portfolio company is a company–fund pair, and holds the investment data.
  • Amounts are in fund currency – invested capital, FMV, acquisition cost, proceeds – unless a field says otherwise. investment.currency tells you which; fmv_local and fmv_local_currency carry the pre-conversion figures. Use /fx if you need to convert, and never add up numbers from different funds without checking their currencies first.
  • invested_capital is the total invested into a company; total_acquisition_cost adds transaction costs on top.
  • Performance figures come precomputed. investment.moic and investment.irr are returned per portfolio company – use them rather than recomputing, so your numbers match what the app shows. If you do need MOIC for an arbitrary grouping, it's (fmv + total_proceeds) / total_acquisition_cost.
  • Dates are yyyy-mm-dd, currencies are 3-letter ISO 4217 codes, and countries are full display names.
  • List endpoints are paginated: { data, pagination: { total, limit, offset } }, default limit 500, maximum 1000. Loop on offset until you've read total.

Pasting that list into your agent's prompt alongside the spec URL measurably improves the first draft.

When to use the MCP server instead

If you want answers rather than an integration – "which companies are above 3x MOIC?" – don't build anything. The MCP server connects Claude, ChatGPT or Cursor directly to your workspace over OAuth, and the assistant queries the API for you. Build a custom integration when you need something to run repeatedly and unattended: a sync into your data warehouse, an internal dashboard, a scheduled export.

Keeping up with changes

The spec is generated from the API's route definitions, so it's never out of step with what's deployed. Regenerate your client after we ship changes – worth wiring into CI:

npx openapi-typescript https://api.fundra.com/v1/openapi.json -o src/fundra.d.ts
git diff --exit-code src/fundra.d.ts

Additive changes (new endpoints, new optional fields) land without warning; we'll give notice before anything breaking.

Browse the endpoints in the API reference, or email hello@fundra.com if something you need isn't exposed yet.

On this page