# Jolv API
> Read-only access to Jolv fund and valuation data. Read-only, under the rights of the Jolv account that authorised the access.
## Get started
- [Introduction](https://www.jolv.app/api/introduction.md): Read-only access to Jolv fund and valuation data, for fund administrators, BI tools, Excel and AI agents.
- [Quickstart](https://www.jolv.app/api/quickstart.md): Authorise once, then read the published NAV of your funds.
- [Authentication](https://www.jolv.app/api/authentication.md): OAuth 2.1 with consent in Jolv. Tokens are issued by Jolv's own authorisation server and carry the rights of the account that authorised the access.
## Integrate
- [Excel and Power BI](https://www.jolv.app/api/excel-power-bi.md): Read Jolv data with Power Query, in Excel or Power BI Desktop, without code.
- [Server integrations](https://www.jolv.app/api/server-integrations.md): Unattended access for fund administrators and scheduled jobs, always within a Jolv subscription and under a user profile.
- [AI agents (MCP)](https://www.jolv.app/api/ai-agents.md): Connect Jolv to Claude, ChatGPT, Gemini Enterprise, Microsoft 365 Copilot, Cursor or VS Code through the Model Context Protocol. Read-only, under each user's own permissions.
## Reference
- [Conventions](https://www.jolv.app/api/conventions.md): Verbs, parameters, units, filters, caching, rate limits and versioning.
- [Errors](https://www.jolv.app/api/errors.md): Every error is a JSON object with a stable code.
- [Changelog](https://www.jolv.app/api/changelog.md): What changed in the Jolv API and MCP server.
## API reference
- [OpenAPI specification](https://jolv-mcp.vercel.app/v1/openapi.json): 34 read-only endpoints, parameters and response schemas.
- [Overview](https://www.jolv.app/api/reference)
- [Fund synthesis](https://www.jolv.app/api/reference/get_fund_synthesis): GET /v1/get_fund_synthesis. Returns the published NAV of one or all accessible funds, with its as-of date: NAV, distributed, cost, MoIC/TVPI, DPI, RVPI, net IRR. A fund without a published finalised campaign is reported as “not published”. Read-only.
- [Fund profile](https://www.jolv.app/api/reference/get_fund_profile): GET /v1/get_fund_profile. Returns the profile of a fund (or of all funds): strategy, vintage, sizes (target / committed / called / distributed), fees, legal structure, metrics (NAV / TVPI / DPI / RVPI / IRR), management team and investment criteria. Read-only.
- [Portfolio overview](https://www.jolv.app/api/reference/get_portfolio_overview): GET /v1/get_portfolio_overview. Returns published NAV aggregates (total and by fund): NAV, invested cost, distributed, TVPI, DPI, active / exited holdings and as-of date. Funds without a published NAV are flagged. Read-only.
- [Portfolio allocation](https://www.jolv.app/api/reference/get_allocation): GET /v1/get_allocation. Returns the breakdown of published NAV by dimension: sector, country, asset type or fund (weights in %). Read-only.
- [Positions by instrument (LP)](https://www.jolv.app/api/reference/get_lp_positions): GET /v1/get_lp_positions. Returns positions by instrument (snapshot): cost, fair value, provision, IFRS level. Read-only.
- [Governance and access (fund)](https://www.jolv.app/api/reference/get_team_access): GET /v1/get_team_access. Returns a fund's access governance: breakdown of effective roles (responsible / validator / viewer…) and attached auditors (firms). Read-only, no personal data.
- [Valuation campaigns](https://www.jolv.app/api/reference/list_campaigns): GET /v1/list_campaigns. Lists valuation campaigns (by fund or all): name, fund, valuation date, status (draft / changes_requested / finalized) and finalisation date. `updated_since` keeps only campaigns created or finalised since that date. Read-only.
- [Valuation sheet](https://www.jolv.app/api/reference/get_valuation_fiche): GET /v1/get_valuation_fiche. Returns a company's persisted valuation sheet: 100% equity, fund share of fair value, IPEV method, provision, comment. Read-only.
- [Valuation method (detail)](https://www.jolv.app/api/reference/get_valuation_method): GET /v1/get_valuation_method. Returns how a company's valuation was built: weighted methods, resulting equity per method, and key inputs (multiple, DLOM, net financial debt, post-money). Read-only.
- [Valuation evolution](https://www.jolv.app/api/reference/get_valuation_evolution): GET /v1/get_valuation_evolution. Returns the evolution of a company's published fair value across its finalised campaigns, by fund (change from one campaign to the next, 100% equity, method, exit, distributed), and the recorded movements. Read-only.
- [Distribution waterfall](https://www.jolv.app/api/reference/get_waterfall): GET /v1/get_waterfall. Returns a company's persisted waterfall: distributable amount, allocation by layer (debt / preference / ratchet / residual) and by holder. Read-only, output of the V4 engine (no recomputation).
- [Audit thread](https://www.jolv.app/api/reference/get_audit_thread): GET /v1/get_audit_thread. Returns the chronological audit thread of a valuation (creation, inputs, method, submission, finalisation). Read-only, immutable audit trail.
- [Listed comparables](https://www.jolv.app/api/reference/get_comparables): GET /v1/get_comparables. Returns a company's panel of listed comparables (most recent research): EV/EBITDA, EV/revenue and P/E medians and the list of listed peers. Read-only.
- [Find a company](https://www.jolv.app/api/reference/find_company): GET /v1/find_company. Finds a company by name (or a fragment of it), ignoring case and accents, and returns its UUID, status, sector and holding funds. Use it to resolve a name before calling UUID-based endpoints. Read-only.
- [Portfolio (holdings)](https://www.jolv.app/api/reference/list_portfolio): GET /v1/list_portfolio. Lists the holdings in the published NAV of a fund (or of all funds): retained fair value, invested cost, distributed at the as-of date, MoIC, sector, ownership %, exits. Read-only.
- [Company financials](https://www.jolv.app/api/reference/get_company_financials): GET /v1/get_company_financials. Returns a company's financial history in IPEV order (revenue → EBITDA → EBIT → net income), with net financial debt and headcount, by year (€m). Read-only.
- [Ownership chain (look-through)](https://www.jolv.app/api/reference/get_company_chain): GET /v1/get_company_chain. Returns a company's ownership chain (HoldCo/OpCo tiers) with the tier-to-parent ownership %, and the cash and debt of each entity. Read-only.
- [Competitors](https://www.jolv.app/api/reference/get_competitors): GET /v1/get_competitors. Returns the competitors identified for a portfolio company (name, website, relevance score, LinkedIn). Read-only.
- [Financial alerts](https://www.jolv.app/api/reference/get_financial_alerts): GET /v1/get_financial_alerts. Returns the financial (risk) alerts of a company or of the organisation: severity, risk score, message, status. Read-only.
- [Cap table](https://www.jolv.app/api/reference/get_cap_table): GET /v1/get_cap_table. Returns a company's cap table: holders (funds and co-investors) with securities by category (shares, preferred shares, bonds, convertible bonds, ORA, warrants, shareholder loans), ownership and fully diluted %, plus the instrument register. Read-only.
- [Instrument detail](https://www.jolv.app/api/reference/get_instrument_detail): GET /v1/get_instrument_detail. Returns the detail of a company's instruments: register (type, holder, value), fair value by instrument type (latest finalised valuation, when computed) and amendments. Read-only.
- [Operations (company history)](https://www.jolv.app/api/reference/get_operations): GET /v1/get_operations. Returns the chronological history of a company's operations (acquisition, follow-on, disposal, exit, dividend) with amounts and instruments. `updated_since` keeps only operations created or modified since that date. Read-only.
- [Distributions and exits](https://www.jolv.app/api/reference/get_distributions): GET /v1/get_distributions. Returns realised distributions (dividends, disposals, exits) and pending conditional distributions (earn-out, escrow) for a company or a fund, with the total distributed. Read-only.
- [Pipeline / deal flow](https://www.jolv.app/api/reference/list_pipeline): GET /v1/list_pipeline. Lists pipeline opportunities by stage (sourcing → closing) with requested ticket and valuation, next action and status (including rejected). Read-only.
- [Deal sheet](https://www.jolv.app/api/reference/get_deal): GET /v1/get_deal. Returns a pipeline opportunity's deal sheet: stage, requested ticket and valuation, brief (summary, strengths, points of attention, next steps) and next actions. Read-only.
- [Intake / inbox](https://www.jolv.app/api/reference/get_intake): GET /v1/get_intake. Returns inbound submissions (intake forms / inbox) with their AI pre-analysis (score, deal-breaker, processing status). Read-only.
- [Activity log](https://www.jolv.app/api/reference/get_activity_log): GET /v1/get_activity_log. Returns the organisation's activity log: interactions recorded on companies (meetings, notes, e-mails, events), most recent first. Read-only.
- [Jolv Network M&A transactions](https://www.jolv.app/api/reference/list_network_deals): GET /v1/list_network_deals. Lists M&A transactions from the Jolv Network (approved cross-organisation transaction comparables): target, sectors, country, EV (€m), EV/EBITDA and EV/revenue multiples, deal type, source. Read-only.
- [Company contacts](https://www.jolv.app/api/reference/get_contacts): GET /v1/get_contacts. Returns the contacts and executives attached to a company (name, role, e-mail, phone, LinkedIn). Read-only.
- [Calendar and events](https://www.jolv.app/api/reference/get_calendar): GET /v1/get_calendar. Returns the calendar of a company or of the organisation: meetings and activities (deal_activities) and milestones (company_events), sorted by date. Read-only.
- [Documents (metadata)](https://www.jolv.app/api/reference/list_documents): GET /v1/list_documents. Lists the documents attached to a company (name, category, date). Metadata only, no content and no download link. `updated_since` keeps only documents uploaded since that date. Read-only.
- [News monitoring](https://www.jolv.app/api/reference/get_veille): GET /v1/get_veille. Returns a company's monitored news (title, opportunity/threat classification, impact score, source) and its synthesis, or the organisation's recent news. Read-only.
- [ESG answers](https://www.jolv.app/api/reference/get_esg): GET /v1/get_esg. Returns the ESG answers recorded for a company, enriched with the framework (indicator, question, section). Read-only.
- [Search valuation guidelines](https://www.jolv.app/api/reference/search_guidelines): GET /v1/search_guidelines. Full-text search in valuation guidelines (IPEV, France Invest, AICPA); returns the relevant excerpts with their source. Read-only.
---
# Introduction
> Read-only access to Jolv fund and valuation data, for fund administrators, BI tools, Excel and AI agents.
Jolv is a valuation platform for private equity and venture capital funds: IPEV-compliant valuation campaigns, immutable audit trail, freeze & lock, approval workflows. The Jolv API lets the systems around a fund read what Jolv holds, without re-keying.
:::cards
- [Quickstart](/api/quickstart) — Your first call in five minutes: authorise, then read the published NAV of your funds.
- [Authentication](/api/authentication) — OAuth 2.1 with consent in Jolv. Every call runs under the rights of the account that authorised it.
- [Excel and Power BI](/api/excel-power-bi) — Pull valuation sheets and fund synthesis into Power Query, no code.
- [API reference](/api/reference) — 34 endpoints with parameters, response schemas and a live playground.
:::
## Principles
:::accordion Read-only
No endpoint writes to Jolv. Every value returned was persisted by a finalised valuation campaign: Jolv is the system of record, the API neither recomputes nor estimates. A valuation that is not finalised has no value in the API.
:::
:::accordion Under your rights
Each call runs with the rights of the Jolv account that authorised the access: organisation, accessible funds, role, MFA, suspension. Through the API you see exactly what you see in the application, no more. The API server has no identity of its own and holds no secret.
:::
:::accordion One vocabulary, two transports
The same 34 reads are available to AI agents over MCP (`/mcp`) and to any software over REST (`/v1/…`): same names, same parameters, same JSON response.
:::
:::accordion EU residency
The API runs in Frankfurt (Vercel `fra1`); the database is in the EU (Supabase `eu-central-1`). Access tokens are issued by Jolv's own authorisation server. This documentation is served by Jolv too: no third-party script, no tracking.
:::
## What the API covers
| Family | Reads |
|---|---|
| **Funds** | Fund synthesis (published NAV, TVPI, DPI, RVPI, net IRR), fund profile, portfolio overview, allocation, positions by instrument, access governance |
| **Valuations** | Valuation sheet, method detail, evolution across campaigns, waterfall, audit thread, listed comparables, instruments, campaigns |
| **Portfolio** | Company search, holdings, cap table, financials, operations, distributions, ownership chain, financial alerts, competitors |
| **Pipeline** | Deal flow, deal sheet, intake, activity log, Jolv Network transactions |
| **Reference data** | Contacts, calendar, documents (metadata), news monitoring, ESG answers, valuation guidelines search |
## What the API does not do
- **No write.** Company financials and cap tables enter Jolv through the existing channels (secure external entry links, file imports), always validated by a person.
- **No webhook.** Use the `updated_since` filter on list endpoints for incremental synchronisation.
- **No file download.** `list_documents` returns metadata only.
- **No investor portal.** Jolv produces and transmits artefacts; it does not host an LP space.
## Support
Write to [contact@jolv.app](mailto:contact@jolv.app) with the endpoint, the time of the call and the `error.code` you received. Never include a token.
---
# Quickstart
> Authorise once, then read the published NAV of your funds.
:::steps
### Get an access token
The API accepts OAuth 2.1 access tokens issued after consent in Jolv. The quickest way to obtain one by hand is any OAuth-capable client (Postman, Insomnia, Bruno):
1. Discovery: `GET https://jolv-mcp.vercel.app/.well-known/oauth-protected-resource` returns the authorisation server.
2. The client registers itself (dynamic client registration), then opens the authorisation URL.
3. Sign in to Jolv (MFA included), review who is asking, click **Authorise**.
4. The client receives an access token, valid for one hour.
See [Authentication](/api/authentication) for the full flow and for unattended server integrations.
### List your funds
```bash cURL
curl "https://jolv-mcp.vercel.app/v1/get_fund_synthesis" \
-H "Authorization: Bearer $JOLV_TOKEN"
```
```python Python
import os, requests
r = requests.get(
"https://jolv-mcp.vercel.app/v1/get_fund_synthesis",
headers={"Authorization": f"Bearer {os.environ['JOLV_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
for fund in r.json()["funds"]:
print(fund["name"], fund["nav_as_of_date"], fund["nav_k_eur"], fund["tvpi"])
```
```javascript JavaScript
const r = await fetch("https://jolv-mcp.vercel.app/v1/get_fund_synthesis", {
headers: { Authorization: `Bearer ${process.env.JOLV_TOKEN}` },
});
if (!r.ok) throw new Error((await r.json()).error.message);
const { funds } = await r.json();
console.table(funds.map(f => ({ name: f.name, asOf: f.nav_as_of_date, navKEur: f.nav_k_eur, tvpi: f.tvpi })));
```
The response is a JSON object with one entry per accessible fund:
```json Response
{
"funds": [
{
"id": "6f1c…",
"name": "Buyout I",
"vintage_year": 2019,
"published": true,
"nav_as_of_date": "2025-12-31",
"source_campaign_id": "a2d4…",
"nav_k_eur": 84210.5,
"distributed_k_eur": 12300,
"cost_k_eur": 61500.2,
"moic": 1.57,
"tvpi": 1.57,
"dpi": 0.2,
"rvpi": 1.37,
"net_irr_pct": 14.2
}
]
}
```
:::note
Values above are illustrative. A fund without a published finalised campaign comes back with `"published": false` and its figures left empty: Jolv never fills a gap with an estimate.
:::
### Walk down to a valuation sheet
A typical fund-administrator path:
1. `GET /v1/list_campaigns?fund_id=…` to find the finalised campaign of the period.
2. `GET /v1/list_portfolio?fund_id=…` for the holdings and their retained fair value.
3. `GET /v1/get_valuation_fiche?company_id=…&campaign_id=…` for the sheet: 100% equity, fund share, IPEV method, provision, comment.
4. `GET /v1/get_audit_thread?entity_id=…` for the immutable audit trail of that valuation.
Every endpoint is documented, with a live playground, in the [API reference](/api/reference).
:::
---
# Authentication
> OAuth 2.1 with consent in Jolv. Tokens are issued by Jolv's own authorisation server and carry the rights of the account that authorised the access.
Every request carries a bearer token:
```http
Authorization: Bearer
```
The token is an OAuth 2.1 access token (JWT, ES256) issued by the Jolv authorisation server. The API verifies its signature, issuer and audience, and relays it to the database: row-level security then applies the rights of the user who authorised the access. Nothing is shared between users, and the API server holds no secret.
:::tip Fastest way to a token
Every endpoint page of the [API reference](/api/reference) has a **Sign in with Jolv to try** button: it runs the flow below in your browser and keeps the token in that tab only, for the live request form. Nothing is stored on Jolv's documentation server.
:::
## Interactive authorisation (a person consents)
This is the flow used by Claude connectors, this documentation's playground and any OAuth-capable client (Postman, Insomnia, Bruno) whose return address is on Jolv's trusted list. The documentation's own return address (`www.jolv.app/api/oauth/callback`) is on that list; a desktop client's local loopback address (`http://127.0.0.1:/…`) is accepted too.
:::steps
### Discovery
`GET https://jolv-mcp.vercel.app/.well-known/oauth-protected-resource`
```json
{
"resource": "https://jolv-mcp.vercel.app/mcp",
"authorization_servers": ["https://pfaotkgjdsrgzrqesuup.supabase.co/auth/v1"],
"scopes_supported": ["openid", "email", "profile"],
"bearer_methods_supported": ["header"],
"resource_name": "Jolv"
}
```
The authorisation server publishes its own metadata (authorisation, token and registration endpoints) at `/.well-known/oauth-authorization-server` under that base URL.
### Client registration
The client registers itself with dynamic client registration (RFC 7591) and receives a `client_id`. No manual approval is needed.
### Consent in Jolv
The client opens the authorisation URL (authorisation code flow with PKCE). The user signs in to Jolv, MFA included if enabled on the account, sees which application asks for access, and clicks **Authorise** or **Refuse**.
### Token
The client exchanges the code at the token endpoint and receives an access token valid for **one hour**. It sends it on every call. When the token expires, the API answers `401` with a `WWW-Authenticate` header pointing back to the discovery document.
:::
:::warning
A session token of the Jolv web application is **refused** by the API, even though it is signed by the same authorisation server: only tokens issued through the consent flow (carrying a `client_id`) are accepted. Consent is explicit, every time.
:::
## Rights and scope
The API does not have its own permission model. The token identifies a Jolv user; the database applies that user's organisation, fund access list, role and status on every row. Consequences:
- A fund or company outside the user's rights is not an error: it is simply absent from the response (empty list, `"published": false`).
- Suspending the user, or removing a fund from their access, takes effect on the next call.
- A user who can see three funds in the application sees the same three funds through the API.
## Revocation
- Remove the integration on the client side, or
- Revoke the authorisation in the Jolv authorisation server (Supabase Auth → OAuth Apps).
An access token already issued stays valid until it expires (one hour at most), like a web session.
## Unattended integrations
A server that runs without a person (nightly ETL, fund administrator sync) cannot click **Authorise**. See [Server integrations](/api/server-integrations).
---
# Excel and Power BI
> Read Jolv data with Power Query, in Excel or Power BI Desktop, without code.
Power Query (the data engine of Excel and Power BI Desktop) reads JSON over HTTPS with a custom header. Three steps.
:::steps
### Get an access token
Follow [Authentication](/api/authentication) with any OAuth-capable client, and copy the access token. It is valid for one hour; a scheduled refresh in the Power BI service needs the [server setup](/api/server-integrations).
### Connect
In Excel: **Data → Get Data → From Other Sources → From Web**. In Power BI Desktop: **Get data → Web**. Choose **Advanced**, enter the endpoint URL and add the HTTP header `Authorization` with the value `Bearer `.
### Shape the table
Power Query opens the JSON record. Click the list you want (for example `funds`), then **To Table**, then expand the column to get one column per field.
:::
## Ready-made queries
Paste these in **Advanced Editor** (replace the token).
```powerquery Fund synthesis
let
Source = Json.Document(Web.Contents(
"https://jolv-mcp.vercel.app/v1/get_fund_synthesis",
[Headers = [Authorization = "Bearer "]])),
Funds = Table.FromRecords(Source[funds]),
Typed = Table.TransformColumnTypes(Funds, {
{"nav_k_eur", type number}, {"distributed_k_eur", type number}, {"cost_k_eur", type number},
{"tvpi", type number}, {"dpi", type number}, {"rvpi", type number}, {"net_irr_pct", type number},
{"nav_as_of_date", type date}})
in
Typed
```
```powerquery Portfolio of a fund
let
FundId = "",
Source = Json.Document(Web.Contents(
"https://jolv-mcp.vercel.app/v1/list_portfolio",
[Query = [fund_id = FundId], Headers = [Authorization = "Bearer "]])),
Holdings = Table.FromRecords(Source[holdings])
in
Holdings
```
```powerquery Campaigns changed since a date
let
Source = Json.Document(Web.Contents(
"https://jolv-mcp.vercel.app/v1/list_campaigns",
[Query = [updated_since = "2026-01-01"], Headers = [Authorization = "Bearer "]])),
Campaigns = Table.FromRecords(Source[campaigns])
in
Campaigns
```
:::tip
Pass parameters with the `Query` option rather than by concatenating them into the URL: Power Query then encodes them correctly, and the credential stays attached to the base URL.
:::
## Units and formats
- Amounts are in euros (€), thousands (€k) or millions (€m) depending on the field. The unit is in the field name (`nav_k_eur`) and in the [API reference](/api/reference). Convert once in Power Query, not in every report.
- Multiples are plain numbers (`1.57` means 1.57×). Percentages are plain numbers (`14.2` means 14.2 %).
- Dates are ISO (`2025-12-31`); set the column type to date.
- `null` means "not published" or "not applicable", never zero.
## Refresh
Each refresh calls the API again. A token older than one hour fails with `401`: edit the header with a fresh token, or move to a [server integration](/api/server-integrations) for scheduled refreshes.
---
# Server integrations
> Unattended access for fund administrators and scheduled jobs, always within a Jolv subscription and under a user profile.
A server cannot perform the consent step itself. Unattended access therefore always starts from a Jolv account of the organisation, whose profile bounds what the integration can read.
## Recommended setup
:::steps
### Create an integration account
Ask a Jolv administrator of the organisation to invite a dedicated account (for example `integration@your-firm.com`). Accounts are created by invitation only. Give it the **viewer** role and only the funds the integration needs. The account's rights are the integration's rights.
### Authorise once
A person signs in with that account and completes the [interactive authorisation](/api/authentication) from the integration's OAuth client. Keep the tokens the client receives in your secret store.
### Renew without a person
If the authorisation server issued a refresh token alongside the access token, the integration renews its access token at the token endpoint without any further consent. Access stops as soon as the authorisation is revoked or the account is suspended.
:::
:::note
Refresh-token issuance and lifetime are settings of the Jolv authorisation server. If your client did not receive a refresh token, contact Jolv before building a scheduled job: an hourly access token alone is not enough for unattended use.
:::
## Organisation API keys
API keys bound to an organisation are not available yet. When they ship, each key will be attached to a Jolv user whose profile bounds the key's scope, exactly like the setup above: there will never be a key that reads more than a user can see.
## Good practice
- One integration account per external system, named after it, so the audit log tells who read what.
- Use `updated_since` on `list_campaigns`, `list_documents`, `get_operations`, `get_financial_alerts` and `get_activity_log` to synchronise incrementally.
- Expect `429` with a `Retry-After` header on bursts, and back off accordingly.
- Never log access tokens. The API never logs request parameters or response data either.
---
# AI agents (MCP)
> Connect Jolv to Claude, ChatGPT, Gemini Enterprise, Microsoft 365 Copilot, Cursor or VS Code through the Model Context Protocol. Read-only, under each user's own permissions.
Jolv exposes its data to AI assistants through the Model Context Protocol (MCP), a read-only server at:
```text Endpoint
https://jolv-mcp.vercel.app/mcp
```
It is the same code as the REST API: one tool per endpoint, same parameters, same response, same authorisation under the user's own Jolv account. An assistant cannot see more than the person who connected it, and it cannot write anything.
Agent setup prompt
Paste this in any MCP-capable assistant to have it connect itself and explain what it can read.
```text Setup prompt
Connect to the Jolv MCP server at https://jolv-mcp.vercel.app/mcp (streamable HTTP).
Authentication is OAuth 2.1 with dynamic client registration: open the authorisation
page it returns, sign in with your Jolv account and click Authorise. The server is
read-only and scoped to my own Jolv permissions. Once connected, list the available
tools, then call get_fund_synthesis to show the published NAV of the funds I can see,
and tell me which other reads (valuation sheets, waterfalls, audit threads, portfolio,
cap tables, deal flow) you can use.
```
## Supported clients
Any client that supports **remote MCP over streamable HTTP with OAuth 2.1 and dynamic client registration** can connect. Jolv's consent page only returns the authorisation code to the clients below; another client is refused at the consent step and no data is shared.
| Client | How to add Jolv | Return address accepted |
|---|---|---|
| **Claude** (web, desktop, mobile, Claude Code) | Settings → Connectors → Add custom connector → URL above | `claude.ai`, `claude.com`, local loopback |
| **ChatGPT** (Business, Enterprise, Edu; developer mode) | Settings → Connectors → Create → MCP server URL above, OAuth | `chatgpt.com` |
| **Gemini Enterprise** | Admin → Tools → Add MCP tool → URL above, OAuth | `vertexaisearch.cloud.google.com` |
| **Microsoft 365 Copilot** (Copilot Studio) | Agent → Tools → Add tool → Model Context Protocol → URL above, OAuth 2.0 | `global.consent.azure-apim.net`, `token.botframework.com` |
| **Cursor** | Settings → MCP → Add server → type `streamable-http`, URL above | `cursor.com`, `cursor:` scheme, local loopback |
| **VS Code** (Copilot agent mode) | Command palette → MCP: Add Server → HTTP → URL above | `vscode.dev`, `vscode:` scheme, local loopback |
:::note
Claude is verified end to end in production. The other clients follow the same standard and their return addresses are on Jolv's trusted list; if your client is refused at the consent step, the page shows the address it used — send it to contact@jolv.app and it will be reviewed.
:::
## Step by step with Claude
:::steps
### Add the connector
In Claude, open Settings → Connectors, choose **Add custom connector**, name it Jolv and paste the endpoint above. Leave the OAuth fields empty: Claude discovers them.
### Authorise
Claude opens the Jolv consent page. Sign in (MFA included if enabled on your account), check which application asks for access, and click **Authorise**.
### Ask
For example: *"What is the published NAV of Buyout I and how did the fair value of each holding move since the previous campaign?"*
:::
A guided version with screenshots is available on the Jolv website: [Connect Claude to Jolv](https://www.jolv.app/features/mcp-server/guide).
## What the assistant can read
The tool names are the endpoint names of the [API reference](/api/reference): `get_fund_synthesis`, `get_valuation_fiche`, `get_waterfall`, `get_audit_thread`, `list_portfolio`, `get_cap_table`, `list_pipeline`… Tool descriptions are in French, the working language of most Jolv teams; this documentation is the English reference for the same reads.
The connector answers from persisted values only. It never estimates, never writes, and tells you when a fund has no published NAV.
## Revoking an assistant
Remove the connector on the client side, or revoke the authorisation in the Jolv authorisation server (Supabase Auth → OAuth Apps). An access token already issued expires within one hour.
---
# Conventions
> Verbs, parameters, units, filters, caching, rate limits and versioning.
| Topic | Rule |
|---|---|
| Base URL | `https://jolv-mcp.vercel.app` |
| Verbs | `GET /v1/{endpoint}?param=value`. `POST /v1/{endpoint}` with a JSON object body (`application/json`) is accepted too, with the same result, for clients that cannot send long query strings; the OpenAPI specification documents the GET form only. With POST, the query string must be empty. |
| Lists | Comma-separated values (`ids=a,b`) or repeated keys (`ids=a&ids=b`). |
| Types | Numbers and booleans are converted from the query string (`limit=5`, `include_dismissed=true`). |
| Unknown parameters | Rejected with `400`, as is a repeated key on a scalar parameter or a POST body that is not an object. Nothing is ignored silently. |
| Incremental filter | `updated_since` (`YYYY-MM-DD` or ISO 8601) on `list_campaigns`, `list_documents`, `get_operations`, `get_financial_alerts`, `get_activity_log`. |
| Amounts | `€`, `€k` or `€m` depending on the field; the unit is in the field name and description. |
| Multiples and percentages | Plain numbers: `1.57` is 1.57×, `14.2` is 14.2 %. |
| Dates | ISO `YYYY-MM-DD`; timestamps ISO 8601 in UTC. |
| Nulls | `null` means not published, not applicable or unknown. Never zero. |
| Caching | None: `Cache-Control: private, no-store`. |
| Rate limit | Per user, against bursts; `429` with `Retry-After` beyond it. Not a contractual quota. |
| CORS | Browser calls are accepted from `jolv.app` origins only (this documentation's playground). Server-side calls are unaffected. |
| Pagination | None. List endpoints return the full set within the user's rights, bounded by `limit` where the endpoint has one (see each page). There is no cursor to follow. |
| Environments | One environment, production. There is no public sandbox: use a dedicated account of your own organisation with the funds you want to expose. |
| SDKs | None published. The OpenAPI specification works with any generator (openapi-generator, Kiota, Stainless); each endpoint page carries cURL, Python, JavaScript and Power Query samples. |
| Inventory | `GET /v1` lists the endpoints and their parameters; `GET /v1/openapi.json` is the machine-readable specification. |
| Support | contact@jolv.app, with the endpoint, the time of the call and the `error.code` received. Never send a token. |
## Versioning
The path is prefixed with `/v1`. A field can be **added** without a version change; removing or renaming a field will go through `/v2`, with the previous version kept available during a transition announced in the [changelog](/api/changelog).
## Identifiers
Funds, companies, campaigns and valuations are identified by UUIDs, stable over time. `find_company` resolves a name (case- and accent-insensitive) to a company UUID; `list_campaigns` and `get_fund_synthesis` give fund and campaign UUIDs.
## For agents and crawlers
Every page of this documentation is also available as Markdown by adding `.md` to its address; [`/api/llms.txt`](/api/llms.txt) lists them all and [`/api/llms-full.txt`](/api/llms-full.txt) concatenates them in one file.
---
# Errors
> Every error is a JSON object with a stable code.
```json Error response
{
"error": {
"code": "invalid_parameter",
"message": "Invalid parameter.",
"details": [{ "path": "company_id", "message": "Required" }]
}
}
```
| HTTP | `error.code` | Meaning |
|---|---|---|
| 400 | `invalid_parameter` | Missing, unknown, mistyped or unreadable parameter; malformed JSON body; POST with a query string. `details` lists the offending paths when known. |
| 401 | `unauthorized` | Missing, expired or invalid token, or a token not issued through the consent flow. The `WWW-Authenticate` header points to the discovery document. |
| 404 | `not_found` | Unknown endpoint (checked after the token). `GET /v1` lists the endpoints. |
| 405 | `method_not_allowed` | Method other than GET or POST. |
| 413 | `invalid_parameter` | Body larger than 1 MB. |
| 415 | `unsupported_media_type` | POST body that is not `application/json`. |
| 429 | `rate_limited` | Too many requests for this user. Wait for `Retry-After` seconds. |
| 500 | `read_failed` | The read failed on the database side. The message is generic; details are in Jolv's logs. |
:::note
A resource outside your rights is **not** an error. It is absent from the response: an empty list, or a fund reported with `"published": false`. This mirrors the application and keeps the API from revealing what exists outside your scope.
:::
---
# Changelog
> What changed in the Jolv API and MCP server.
:::update 13 October 2026 | v0.5.0
**REST API v1.** The 34 read-only tools of the MCP server are now available over REST at `/v1/{endpoint}`, with the same OAuth token and the same rights. OpenAPI 3.0 specification at `/v1/openapi.json`, this documentation, CORS for the playground, uniform JSON errors, per-user burst limit.
:::
:::update 8 October 2026 | v0.4.0
**Incremental filter.** `updated_since` on `list_campaigns`, `list_documents`, `get_operations`, `get_financial_alerts` and `get_activity_log`.
:::
:::update 30 September 2026 | v0.3.0
**Per-user OAuth.** The MCP server no longer has a shared identity: each user connects with their own Jolv account through OAuth 2.1 served by Jolv's authorisation server, with consent in Jolv. Every call runs under that user's rights.
:::
---
# Fund synthesis
> Funds · GET /v1/get_fund_synthesis
Returns the published NAV of one or all accessible funds, with its as-of date: NAV, distributed, cost, MoIC/TVPI, DPI, RVPI, net IRR. A fund without a published finalised campaign is reported as “not published”. Read-only.
Query parameters:
- fund_id (uuid, optional): Fund UUID. Omitted → all accessible funds.
---
# Fund profile
> Funds · GET /v1/get_fund_profile
Returns the profile of a fund (or of all funds): strategy, vintage, sizes (target / committed / called / distributed), fees, legal structure, metrics (NAV / TVPI / DPI / RVPI / IRR), management team and investment criteria. Read-only.
Query parameters:
- fund_id (uuid, optional): Fund UUID (optional; default = all).
---
# Portfolio overview
> Funds · GET /v1/get_portfolio_overview
Returns published NAV aggregates (total and by fund): NAV, invested cost, distributed, TVPI, DPI, active / exited holdings and as-of date. Funds without a published NAV are flagged. Read-only.
Query parameters:
- fund_id (uuid, optional): Fund UUID (optional; default = all).
---
# Portfolio allocation
> Funds · GET /v1/get_allocation
Returns the breakdown of published NAV by dimension: sector, country, asset type or fund (weights in %). Read-only.
Query parameters:
- by (enum, optional): Breakdown dimension (default: sector).
- fund_id (uuid, optional): Restrict to one fund (optional).
---
# Positions by instrument (LP)
> Funds · GET /v1/get_lp_positions
Returns positions by instrument (snapshot): cost, fair value, provision, IFRS level. Read-only.
Query parameters:
- company_id (uuid, optional): Company UUID (optional).
- fund_id (uuid, optional): Fund UUID (optional).
---
# Governance and access (fund)
> Funds · GET /v1/get_team_access
Returns a fund's access governance: breakdown of effective roles (responsible / validator / viewer…) and attached auditors (firms). Read-only, no personal data.
Query parameters:
- fund_id (uuid, optional): Fund UUID (optional; default = all accessible funds).
---
# Valuation campaigns
> Campaigns · GET /v1/list_campaigns
Lists valuation campaigns (by fund or all): name, fund, valuation date, status (draft / changes_requested / finalized) and finalisation date. `updated_since` keeps only campaigns created or finalised since that date. Read-only.
Query parameters:
- fund_id (uuid, optional): Fund UUID (optional).
- updated_since (string, optional): Only return items created or modified since this date (YYYY-MM-DD or ISO 8601 timestamp, optional).
---
# Valuation sheet
> Valuations · GET /v1/get_valuation_fiche
Returns a company's persisted valuation sheet: 100% equity, fund share of fair value, IPEV method, provision, comment. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- campaign_id (uuid, optional): Campaign UUID (optional; default = latest finalised).
---
# Valuation method (detail)
> Valuations · GET /v1/get_valuation_method
Returns how a company's valuation was built: weighted methods, resulting equity per method, and key inputs (multiple, DLOM, net financial debt, post-money). Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- campaign_id (uuid, optional): Campaign UUID (optional; default = latest finalised).
---
# Valuation evolution
> Valuations · GET /v1/get_valuation_evolution
Returns the evolution of a company's published fair value across its finalised campaigns, by fund (change from one campaign to the next, 100% equity, method, exit, distributed), and the recorded movements. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
---
# Distribution waterfall
> Valuations · GET /v1/get_waterfall
Returns a company's persisted waterfall: distributable amount, allocation by layer (debt / preference / ratchet / residual) and by holder. Read-only, output of the V4 engine (no recomputation).
Query parameters:
- company_id (uuid, required): Company UUID.
- campaign_id (uuid, optional): Campaign UUID (optional).
---
# Audit thread
> Valuations · GET /v1/get_audit_thread
Returns the chronological audit thread of a valuation (creation, inputs, method, submission, finalisation). Read-only, immutable audit trail.
Query parameters:
- entity_id (uuid, required): Valuation UUID (campaign_valuation).
---
# Listed comparables
> Valuations · GET /v1/get_comparables
Returns a company's panel of listed comparables (most recent research): EV/EBITDA, EV/revenue and P/E medians and the list of listed peers. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
---
# Find a company
> Companies · GET /v1/find_company
Finds a company by name (or a fragment of it), ignoring case and accents, and returns its UUID, status, sector and holding funds. Use it to resolve a name before calling UUID-based endpoints. Read-only.
Query parameters:
- query (string, required): Company name (or a fragment). Case- and accent-insensitive.
---
# Portfolio (holdings)
> Companies · GET /v1/list_portfolio
Lists the holdings in the published NAV of a fund (or of all funds): retained fair value, invested cost, distributed at the as-of date, MoIC, sector, ownership %, exits. Read-only.
Query parameters:
- fund_id (uuid, optional): Fund UUID (optional; default = all accessible funds).
---
# Company financials
> Companies · GET /v1/get_company_financials
Returns a company's financial history in IPEV order (revenue → EBITDA → EBIT → net income), with net financial debt and headcount, by year (€m). Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- campaign_id (uuid, optional): Campaign UUID (optional; reads campaign_company_financials).
---
# Ownership chain (look-through)
> Companies · GET /v1/get_company_chain
Returns a company's ownership chain (HoldCo/OpCo tiers) with the tier-to-parent ownership %, and the cash and debt of each entity. Read-only.
Query parameters:
- company_id (uuid, required): UUID of a company in the chain (root or tier).
---
# Competitors
> Companies · GET /v1/get_competitors
Returns the competitors identified for a portfolio company (name, website, relevance score, LinkedIn). Read-only.
Query parameters:
- company_id (uuid, required): Portfolio company UUID.
---
# Financial alerts
> Companies · GET /v1/get_financial_alerts
Returns the financial (risk) alerts of a company or of the organisation: severity, risk score, message, status. Read-only.
Query parameters:
- company_id (uuid, optional): Company UUID (optional; otherwise the whole organisation).
- include_dismissed (boolean, optional): Include dismissed alerts (default false).
- updated_since (string, optional): Only return items created or modified since this date (YYYY-MM-DD or ISO 8601 timestamp, optional).
---
# Cap table
> Cap table & instruments · GET /v1/get_cap_table
Returns a company's cap table: holders (funds and co-investors) with securities by category (shares, preferred shares, bonds, convertible bonds, ORA, warrants, shareholder loans), ownership and fully diluted %, plus the instrument register. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
---
# Instrument detail
> Cap table & instruments · GET /v1/get_instrument_detail
Returns the detail of a company's instruments: register (type, holder, value), fair value by instrument type (latest finalised valuation, when computed) and amendments. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- campaign_id (uuid, optional): Campaign UUID (optional; default = latest finalised).
---
# Operations (company history)
> Operations & distributions · GET /v1/get_operations
Returns the chronological history of a company's operations (acquisition, follow-on, disposal, exit, dividend) with amounts and instruments. `updated_since` keeps only operations created or modified since that date. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- updated_since (string, optional): Only return items created or modified since this date (YYYY-MM-DD or ISO 8601 timestamp, optional).
---
# Distributions and exits
> Operations & distributions · GET /v1/get_distributions
Returns realised distributions (dividends, disposals, exits) and pending conditional distributions (earn-out, escrow) for a company or a fund, with the total distributed. Read-only.
Query parameters:
- company_id (uuid, optional): Company UUID (optional).
- fund_id (uuid, optional): Fund UUID (optional).
---
# Pipeline / deal flow
> Deal flow · GET /v1/list_pipeline
Lists pipeline opportunities by stage (sourcing → closing) with requested ticket and valuation, next action and status (including rejected). Read-only.
Query parameters:
- stage (string, optional): Stage filter (optional): sourcing, analyse, due_diligence, comite, closing.
---
# Deal sheet
> Deal flow · GET /v1/get_deal
Returns a pipeline opportunity's deal sheet: stage, requested ticket and valuation, brief (summary, strengths, points of attention, next steps) and next actions. Read-only.
Query parameters:
- company_id (uuid, required): Company / opportunity UUID.
---
# Intake / inbox
> Deal flow · GET /v1/get_intake
Returns inbound submissions (intake forms / inbox) with their AI pre-analysis (score, deal-breaker, processing status). Read-only.
Query parameters:
- status (string, optional): Filter by status (optional; e.g. new, reviewed).
- limit (integer, optional): Maximum number of items (default 25).
---
# Activity log
> Deal flow · GET /v1/get_activity_log
Returns the organisation's activity log: interactions recorded on companies (meetings, notes, e-mails, events), most recent first. Read-only.
Query parameters:
- type (string, optional): Filter by activity type (optional; e.g. reunion, note, email).
- limit (integer, optional): Maximum number of entries (default 30).
- updated_since (string, optional): Only return items created or modified since this date (YYYY-MM-DD or ISO 8601 timestamp, optional).
---
# Jolv Network M&A transactions
> Deal flow · GET /v1/list_network_deals
Lists M&A transactions from the Jolv Network (approved cross-organisation transaction comparables): target, sectors, country, EV (€m), EV/EBITDA and EV/revenue multiples, deal type, source. Read-only.
Query parameters:
- sector (string, optional): Free-text sector filter (optional, case-insensitive).
- limit (integer, optional): Maximum number of items (default 25).
---
# Company contacts
> Contacts & calendar · GET /v1/get_contacts
Returns the contacts and executives attached to a company (name, role, e-mail, phone, LinkedIn). Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
---
# Calendar and events
> Contacts & calendar · GET /v1/get_calendar
Returns the calendar of a company or of the organisation: meetings and activities (deal_activities) and milestones (company_events), sorted by date. Read-only.
Query parameters:
- company_id (uuid, optional): Company UUID (optional; otherwise the whole organisation).
- limit (integer, optional): Maximum number of entries (default 30).
---
# Documents (metadata)
> Documents, news & ESG · GET /v1/list_documents
Lists the documents attached to a company (name, category, date). Metadata only, no content and no download link. `updated_since` keeps only documents uploaded since that date. Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- updated_since (string, optional): Only return items created or modified since this date (YYYY-MM-DD or ISO 8601 timestamp, optional).
---
# News monitoring
> Documents, news & ESG · GET /v1/get_veille
Returns a company's monitored news (title, opportunity/threat classification, impact score, source) and its synthesis, or the organisation's recent news. Read-only.
Query parameters:
- company_id (uuid, optional): Company UUID (optional; otherwise the organisation's recent news).
- limit (integer, optional): Maximum number of news items (default 20).
---
# ESG answers
> Documents, news & ESG · GET /v1/get_esg
Returns the ESG answers recorded for a company, enriched with the framework (indicator, question, section). Read-only.
Query parameters:
- company_id (uuid, required): Company UUID.
- campaign_id (uuid, optional): Campaign UUID (optional; otherwise all accessible campaigns).
---
# Search valuation guidelines
> Guidelines · GET /v1/search_guidelines
Full-text search in valuation guidelines (IPEV, France Invest, AICPA); returns the relevant excerpts with their source. Read-only.
Query parameters:
- query (string, required): Terms to search in the guidelines (e.g. “DLOM”, “quoted price”).
- limit (integer, optional): Maximum number of excerpts (default 5).