# Kela FundOS — Full API & Integration Reference for AI Agents # Last updated: 2026-06-10 > FundOS by Kela — https://kela.com > Machine-readable integration guide for AI agents, LLMs, and developers. --- ## Authentication All API and MCP calls use Bearer token auth. Defensive note: the server's `_authenticate()` strips an accidental inner `Bearer ` prefix from the token before checking it (so requests with `Authorization: Bearer Bearer vdr_xxx` from agents that double- prefixed the env var still succeed). The CLI does the same client-side in `cli/fundos_cli/config.py::_clean_api_key()`. If you see a 401, the diagnostic block shipped with the CLI prints the redacted key prefix + base URL so you can spot env-mismatch errors in 3 seconds. ### API Key (recommended for AI agents) Generate in Settings → API Keys. Format: starts with `vdr_`. ``` Authorization: Bearer vdr_xxxxxxxxxxxxxxxx ``` ### JWT Token (24-hour, browser sessions) ``` POST https://kela.com/api/v1/auth/login {"email": "...", "password": "..."} → {"token": "eyJ...", "expires_in": 86400} ``` Rate limit: 100 req/min. Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. --- ## MCP Server (Claude, Cursor, other MCP clients) ```bash claude mcp add fundos https://www.kela.com/mcp ``` For SSE-only clients: https://www.kela.com/mcp/sse POST messages to the session URL returned in the SSE endpoint event. ### MCP Endpoints - GET /mcp/sse SSE stream - POST /mcp/message JSON-RPC 2.0 - GET /mcp/info Server capabilities - GET /mcp/tools Full tool list with JSON Schema - POST /mcp/call Simple REST tool call (no SSE needed) ### Available MCP Tools Tools marked * = require human approval before execution (side-effect tools). **Agent Context — call this FIRST** - fundos_get_agent_context Call this FIRST at the start of any multi-step workflow. Returns structured session briefing: recent tool calls, pending human-approval actions, active deals, LP roster changes, open risk alerts, upcoming capital calls, recently uploaded documents, and prior agent runs. Supports lookback_days (default 30, max 90). Read-only, costs 2 credits. **VDR / Deal Rooms** - list_deal_rooms List all deal rooms in the org (use to pick a room to inspect) - get_deal_room Load members + stats for a known room_id - create_deal_room* Spin up a new data room for diligence or LP onboarding (HUMAN APPROVAL) - list_documents Inventory documents in a room before searching or summarising - get_document_metadata Inspect a single document's metadata before downloading - get_document_download_url Fetch the raw download URL for a document file (PDF/XLSX/DOCX) - search_documents Answer free-form questions over a room with citations (RAG search) - list_room_members Audit who has access to a room before granting more - add_room_member* Onboard a collaborator or LP to a room (HUMAN APPROVAL — expanding access) - list_users Match a person by email or build a team-wide report - get_audit_log Investigate suspicious access or build a compliance report - get_document_activity Per-document engagement signals — who actually read it and when - get_signature_status Check DocuSign envelope closing signature status across envelopes - list_qa_questions List diligence Q&A questions in a room (triage the Q&A queue) - answer_qa_question* Post a reviewed answer to an LP-visible Q&A question (HUMAN APPROVAL) **Deal CRM + Transactions + Pricer** - fundos_list_deals Read the full deal pipeline - fundos_get_deal Load full detail on one deal before drafting - fundos_create_deal* Add a qualified pitch or term sheet to the pipeline (HUMAN APPROVAL) - fundos_get_pipeline Render kanban view or compute per-stage deal counts - fundos_list_transactions Report on the closing pipeline or chase condition precedents - fundos_draft_transaction* Start a transaction record with default task pack (HUMAN APPROVAL) - fundos_run_pricer Score an asset: IRR, MOIC, WAL, cashflows, waterfall splits **Risk** - fundos_list_covenants Enumerate all monitored covenants (use to build risk dashboard) - fundos_check_covenant Test a covenant value when fresh financials arrive; alerts on breach - fundos_list_risk_alerts Retrieve the list of open portfolio risk alerts (pass open=true) **ODD / Diligence / CIM** - fundos_generate_odd Draft ODD answers when an LP sends a DDQ - fundos_vdr_analyze Surface red flags + entity map from a document bundle - fundos_list_cim_reports List existing CIMs / teasers / one-pagers - fundos_list_cim_templates Discover available CIM templates before generating - fundos_generate_cim Draft a CIM from source documents for IC or LPs **Investor Portal (LP)** - fundos_list_lps Enumerate all LP investors for rollups or reporting - fundos_get_lp Load full LP detail: commitment, KYC status, capital-call ledger - fundos_create_capital_call* Issue a capital call (HUMAN APPROVAL — this affects LP cash) NOTE: Never automatically send LP capital-call or distribution notices to LP inboxes. Always draft first; humans click send. Route drafts to /fundos/investors/. **CFO Center** - fundos_list_fund_accounts List all fund vehicles — pick one before computing P&L - fundos_compute_pnl Compute P&L + NAV over a date range. READ-ONLY when called with inline entries — does NOT write journal entries to the database. To persist entries, use cfo.post_journal_entry via the web UI (requires human approval). - fundos_compute_waterfall Compute LP/GP splits at exit (European waterfall model) **Syndication** - fundos_list_syndications List syndications and report raise progress - fundos_get_syndication Inspect a single syndication + allocation matrix - fundos_allocate* Record investor allocations (HUMAN APPROVAL) **HF Ops (DTCC ITP)** - hf_ops_dtcc_get_trade_status Investigate a settlement break by ctm_ref - hf_ops_dtcc_list_unaffirmed List confirms still pending T+0 affirmation - hf_ops_dtcc_get_affirmation_scorecard Report ops health to COO/PM - hf_ops_dtcc_lookup_ssi Fetch counterparty SSI when chasing a missing-SSI break **OMS / Trading** - oms_list_orders List orders (filter by status, fund account) - oms_get_order Order detail + execution timeline - oms_create_order* Submit a new order — pre-trade compliance runs automatically (HUMAN APPROVAL) - oms_list_positions Current position book - oms_check_pretrade Dry-run pre-trade compliance check (no order created) - oms_get_fix_status FIX engine sidecar health + per-session state **Compliance OS** - fundos_list_kyc_records List KYC/AML records - fundos_list_filings List regulatory filing deadlines - fundos_check_restricted_list Check if a ticker, ISIN, or company name is on the restricted list - fundos_list_obligations List the compliance obligations register **Utility / Discovery** - fundos_list_tools Discover the full FundOS tool catalogue - fundos_call_tool Invoke any tool by name with validated args - search Search adapter for ChatGPT Deep Research — returns {id, title, url}[] - fetch Read a Kela document's full text (paired with search) ### MCP Resources myvdr://rooms, myvdr://fundos/deals, myvdr://fundos/transactions, myvdr://fundos/covenants, myvdr://fundos/lps, myvdr://fundos/positions ### Dynamic Client Registration (RFC 7591) MCP clients self-register without a pre-configured client_id: ``` POST /oauth/register (no auth required) Content-Type: application/json { "client_name": "Codex CLI", "redirect_uris": ["http://localhost:54321/callback"], "grant_types": ["authorization_code"], "token_endpoint_auth_method": "none" } HTTP 201 { "client_id": "dyn_", "client_id_issued_at": , "grant_types": ["authorization_code"], "redirect_uris": [...], "token_endpoint_auth_method": "none" } ``` Discovery: `registration_endpoint` field in `/.well-known/oauth-authorization-server` and `/.well-known/mcp.json`. Rate limit: 10 registrations / IP / hour. Dynamic clients show `is_dynamic=True` in the DB; admins can revoke at `/admin/oauth/`. ### OAuth Scopes Always default to `read` scope for AI agents doing read-only work. - `read` — read-only access to all FundOS data (RECOMMENDED default for AI agents) - `write` — data entry; required for create/update operations - `admin` — organisation administration; NEVER request for read-only tasks Request `read` for workflows that only inspect data (list deals, read LP info, check covenants). Upgrade to `write` only when the workflow explicitly creates or modifies records (and human approval has been obtained). --- ## REST API Reference Base URL: https://kela.com/api/v1 Interactive docs: https://kela.com/api/docs ### VDR — Deal Rooms GET /rooms List rooms POST /rooms Create room GET /rooms/{id} Room detail + members GET /rooms/{id}/documents List documents POST /rooms/{id}/documents Upload (multipart) GET /rooms/{id}/documents/{doc_id}/download DELETE /rooms/{id}/documents/{doc_id} GET /rooms/{id}/members POST /rooms/{id}/members Invite {email, role} GET /rooms/{id}/qa Q&A questions POST /rooms/{id}/qa/{q_id}/answer GET /rooms/{id}/analytics/audit ### FundOS — Deal CRM GET /api/v1/fundos/crm/deals List deals POST /api/v1/fundos/crm/deals Create deal (?ephemeral=true to dry-run) GET /api/v1/fundos/crm/deals/{id} PATCH /api/v1/fundos/crm/deals/{id} GET /api/v1/fundos/crm/pipeline Deals grouped by stage ### FundOS — LP CRM GET /api/v1/fundos/lp-crm/investors POST /api/v1/fundos/lp-crm/investors/{id}/activity LP CRM Fundraising Pipeline (web UI, /fundos/lp-crm/...): - pipeline — 8-stage kanban (Identified→First Contact→Intro Meeting→Due Diligence→Soft Commit→Hard Commit→Closed/Won→Passed). Drag-and-drop cards; each move auto-logs a Stage Change signal. - analytics — Arc gauge (% of target raise committed), KPI cards, pipeline funnel (horizontal bars per stage), recent signals feed. - agent — AI outreach agent config: fund description, key differentiators, target LP profile, preferred tone, follow-up cadence. - POST //move-stage — JSON; moves LP to new stage; logs signal. - POST //log-signal — JSON; manually log a buying-intent signal (document_viewed, email_opened, meeting_attended, question_asked, referral, inbound_inquiry, follow_up_requested, no_reply, stage_change). - POST //draft-outreach — JSON {channel}; calls Gemini to draft email or LinkedIn message using agent config + LP signals; returns {ok, outreach_id, subject, body, suggested_cta}. - POST //outreach//status — JSON {status}; mark draft as sent or discarded. - POST //share-doc — JSON {document_name, share_link}; creates a trackable URL. - GET /track/ — Public (no login); increments view_count, logs document_viewed signal, redirects to original link. - POST //update-targeting — Form; saves target_commitment_usd, soft_commit_usd, hard_commit_usd, fit_score. Signal heat on LP cards: green = signal in last 7d, amber = 8–21d, grey = dormant. ### FundOS — Pricer POST /api/v1/fundos/pricer IRR/MOIC/WAL/waterfall — ?ephemeral=true safe ### FundOS — Risk GET /api/v1/fundos/risk/covenants POST /api/v1/fundos/risk/covenants/{id}/check GET /api/v1/fundos/risk/alerts ### FundOS — Investor Portal GET /api/v1/fundos/investors/lps GET /api/v1/fundos/investors/lps/{id} Includes capital-call ledger POST /api/v1/fundos/investors/lps/{id}/capital-calls ### FundOS — CFO Center GET /api/v1/fundos/cfo/accounts Fund account list POST /api/v1/fundos/cfo/report P&L + NAV computation POST /api/v1/fundos/cfo/waterfall European waterfall splits CFO Center v2 — Fund Performance + Period Close (web UI, /fundos/cfo/accounts//...): - dashboard — 6-tile live overview (MTD/QTD/YTD P&L, Risk Metrics, Top Movers, Period Close, LP Waterfall, Benchmark sparkline) - performance — MTD/QTD/YTD P&L tabs + Chart.js fund vs SPY/QQQ benchmark line chart - risk — Sharpe ratio (12-month), fund leverage (gross/net), bond portfolio DV01 - movers — Top 10 P&L contributors by position (DAILY/MTD/QTD/YTD) - period-close — Run month/quarter/year-end closes; locks P&L; runs LP waterfall (HF: on realized+unrealized; PE/VC/PC: on realized only) - period-close/ — LP waterfall allocation detail; HF incentive fee shown as accrual - lp-terms — Per-LP hurdle/carry/preferred return overrides (blank = fund default) - chart-data — JSON endpoint for Chart.js benchmark chart data (SPY, QQQ, Fund NAV) CFO Center Audit Pack (web UI, /fundos/cfo): - Generate a ZIP audit pack (trial balance, LP capital roll-forward, mgmt fee, waterfall, cover memo) for any fund account with a custom as-of date. - View the contents of any generated pack (individual file list with per-file download buttons). - Delete any audit pack (including errored ones) via the trash icon. - Per-account persistent configuration via AuditPackConfig: toggle each of the 5 standard artifacts on/off and attach extra VDR documents to include in the pack. Config is shared across all CFO users in the workspace. - Downloads are proxied through Flask (authenticated); direct DO Spaces URLs are not exposed. OMS Multi-Asset Order Entry (June 2026): - New Order modal supports 8 instrument types: EQUITY, ETF, BOND, HY_BOND, PREFERRED, OPTION, FUTURE, SWAP - Selecting a type dynamically reveals type-specific fields (CUSIP/coupon/maturity/face_value/YTM for bonds; underlying/strike/expiry/option_type for options; contract_code/multiplier/tick_size for futures; swap_type/notional/fixed_rate/floating_index for swaps) - InstrumentSpec rows created alongside orders; position book shows DV01 + Duration columns for bond positions - Benchmark prices (SPY, QQQ) fetched nightly from Finnhub at 9pm UTC via cron /fundos/cfo/cron/benchmark-refresh OMS Tax Lot Tracking (June 2026): - Every buy creates a TaxLot row (FIFO — IRS default lot method) - Every sell matches against open lots oldest-first; realized G/L recorded per lot - Position book: click any position row to expand individual lots with ST/LT badge + unrealized G/L - Short-term: held < 365 days (ordinary income rates); long-term: held ≥ 365 days (preferential 0/15/20%) - Tax Summary page (/fundos/oms/tax-summary): annual realized ST/LT gains/losses + open lot unrealized exposure - Wash-sale detection: flagged when a repurchase occurs within 30 days of a loss close - All figures are informational; consult your tax advisor for 1099-B reconciliation and filing AI FDE — Fund Onboarding Automation (June 2026): The AI FDE automates fund client onboarding end-to-end. An admin creates an onboarding at /fundos/fde/, which generates a shareable link (/onboard/). The fund's COO/CFO chooses between two discovery paths: DISCOVERY PATH A — Document upload (recommended): 1. Client uploads PPM, pitch deck, or any combination of up to 3 PDFs (≤5 MB each). 2. POST /onboard//upload (multipart/form-data, field name "docs") → Gemini multimodal extracts Fund Profile from the documents → Sets discovery_mode="doc_upload" on the FundOnboarding record → Seeds a gap-fill opening message confirming what was extracted → Returns {success, profile, extraction_summary, opening_message} 3. A short 4–6 question follow-up fills in gaps the documents didn't cover (tech stack, pain points, priorities, integration constraints). 4. When follow-up is complete, discovery_complete=true. DISCOVERY PATH B — Q&A interview (fallback): Clients who don't want to share documents or don't have them yet complete a ~30-question async conversation. The opening screen shows 6 fund-type pill buttons; each subsequent turn shows [OPTIONS: A | B | C] pills for finite- answer questions. All state persists so clients can close and return later. Both paths produce the same structured Fund Profile JSON. When complete, the admin clicks Configure to set up the FundAccount, pipeline stages, and LP placeholder. DISCOVERY SCOPE (both paths): fund type (hedge_fund/vc_fund/pe_fund/private_credit/ family_office), AUM, investment strategy, team size, domicile, GP location, launch timeline, regulatory status (SEC/CFTC/AIFMD/FCA), existing systems (prime broker, fund admin, compliance system, PM system, data provider), trading instruments, reporting requirements, pain points, priority deliverables, integration requirements. MODULE SELECTOR RULES: - cfo_center: always enabled - gp_admin_dashboard: always enabled - lp_portal: hedge_fund / pe_fund / vc_fund / private_credit - oms: any trading instruments present - trading_fix_engine: equities / fixed_income / options / futures / fx in instruments - compliance_os: SEC or CFTC registered - deal_room: vc_fund or pe_fund - lp_crm: pe_fund / vc_fund / private_credit Admin routes (login required): GET/POST /fundos/fde/, GET /fundos/fde/runs/, POST /fundos/fde/runs//configure Public routes (token auth): GET /onboard/, POST /onboard//message, POST /onboard//upload, GET /onboard//status The /onboard//message response shape: {reply, choices, status, question_count, discovery_complete} `choices` is a string[] of clickable options stripped from Gemini's [OPTIONS: A|B|C] block. An empty array means the question is free-text. The /onboard//upload response shape: {success: true, profile: {...}, extraction_summary: "...", opening_message: "..."} On failure: {error: "extraction_failed", message: "..."} — client falls back to Q&A path. DB columns on fund_onboardings: discovery_mode ("qa" | "doc_upload"), doc_extraction_json (raw extracted profile + summary + file_count stored as JSON). Model: gemini-2.5-pro by default (override via GEMINI_FDE_MODEL env var without redeploy). Chat turns use thinkingBudget=0; profile extraction uses thinkingBudget=2048. Document extraction uses Gemini multimodal with inline_data base64 PDF parts. Database tables: fund_onboardings, fund_discovery_sessions, fund_impl_documents, fund_impl_tasks, fund_change_requests All discovery turns are billed via gemini_call(feature=fundos.fde.discovery) and linked to AgentRun for observability. Phases 2-5 (planning docs, config orchestration, UAT, change requests) are planned for future builds. ### FundOS — OMS / Trading GET /api/v1/fundos/oms/orders List orders (status, fa_id filters) POST /api/v1/fundos/oms/orders Submit order (runs pre-trade compliance) GET /api/v1/fundos/oms/orders/{id} Order + executions GET /api/v1/fundos/oms/positions Position book POST /api/v1/fundos/oms/pretrade Dry-run compliance check (no order created) GET /api/v1/fundos/oms/fix-status FIX sidecar health + session state ### FundOS — Syndication GET /api/v1/fundos/syndication POST /api/v1/fundos/syndication/{id}/allocate ### Stateless Document API — no FundOS account required Developers, law firms, fund admins, and LPs can call these endpoints with only a `doc_` API key. All data is supplied inline. No fund account, no pre-loaded data, no monthly seat fee. Outcome-based pricing (charged per successful document; first 30 days free; trial credits waive all fees). Get a `doc_` key at https://kela.com/developers/register — email + password, key appears immediately on the dashboard. POST /api/v1/documents/k1 — Schedule K-1 Form 1065 — $5 per partner POST /api/v1/documents/odd — ODD/DDQ completion — $25 per DDQ POST /api/v1/documents/analyze — Document red-flag + entity-map — $3 POST /api/v1/documents/waterfall — European waterfall — free POST /api/v1/documents/pricer — IRR/MOIC/WAL pricer — free Auth for all: `Authorization: Bearer doc_` K-1 minimal body: { "fund_name": "Eight Capital Fund II", # required "tax_year": 2025, # required "partner_name": "Aksia LP", # required "lp_share_pct": 0.15, # optional "capital_account_start": 1000000, # optional "contributions_year": 0, # optional "box_1_ordinary_income": 45000, # income boxes (all optional, default 0) "box_9a_lt_gain": 105000, "box_13_deductions": 2500, "distributions": 0, # OR dist_roc/dist_income/dist_lt/dist_st/dist_recallable "format": "html" # only format supported today } Returns: { "html": "...", "filename": "k1_2025_aksia_lp.html", "charged_usd": 5.00, "charge_reason": "charged" } ODD minimal body: { "fund_info": {"fund_name": "...", "strategy": "VC pre-seed", "aum": 20000000}, "questions": ["Describe your investment process.", "..."] } Returns: { "answers": {...}, "charged_usd": 25.00, "token_usage": {...} } Analyze body: { "documents": [{"name": "cim.pdf", "text": "...full text..."}, ...] } Returns: { "summary": "...", "red_flags": [...], "entity_map": {...}, "charged_usd": 3.00 } Waterfall body: { "distributable": 1000000, "committed": 1000000, "hurdle_pct": 8, "carry_pct": 20 } Returns: { "lp_total": 916000, "gp_total": 84000, "tiers": [...], "charged_usd": 0 } All endpoints: accept `vdr_` OR `doc_` keys; trial_active orgs pay $0 for all. Developer orgs (plan=developer): no seat fee; outcome charges only. Developer dashboard: https://kela.com/developers/dashboard — key table + monthly usage. --- ## Triggering AI Agents FundOS has 8 AI agents (A–H). They are triggered via POST, stream events via SSE, and propose AgentAction rows that humans approve before execution. | Agent | What it does | Trigger endpoint | |-------|-------------|-----------------| | A — LP Fundraising Autopilot | LP follow-up emails, meeting prep | POST /fundos/lp-crm/ → "Run Autopilot" button | | B — Deal Screening | Screens inbound pitch decks | POST /fundos/crm/screen (paste pitch text) | | C — Diligence Agent | VDR red-flag analysis | POST /fundos/vdr/room//diligence/run | | D — Closing Coordinator | Extracts CPs from term sheets | POST /fundos/transactions//extract-cps | | E — CFO Reminder Agent | Capital call reminder ladder | POST /fundos/investors/calls//schedule-reminders | | F — Risk Agent | Covenant + alert portfolio scan | POST /fundos/risk/agent/scan | | G — Deal Team Orchestrator | Multi-agent natural-language | /fundos/team | | H — Compliance Agent | KYC/AML + filing scan | POST /fundos/compliance/agent/scan | ### Approving / rejecting agent actions All proposed actions go through human review: POST /fundos/agent/actions//approve — GP approves and executes the action POST /fundos/agent/actions//reject — GP rejects the action Stream a run's events: GET /fundos/agent/runs//stream — SSE stream (?since= to resume) GET /fundos/agent/runs//events.json — polling fallback when SSE is blocked Nothing auto-executes. Every state-changing action requires a human to click Approve. --- ## Common Agent Workflows ### 1. Due Diligence on an inbound deck 1. fundos_create_deal (ephemeral=true) — validate 2. Human confirms → fundos_create_deal (persist) 3. create_deal_room → spin up diligence room 4. fundos_vdr_analyze → red flags + entity map 5. search_documents for specific terms ### 2. LP fundraising follow-up 1. fundos_list_lps → find target LP 2. fundos_get_lp → commitment + capital-call ledger 3. search_documents (LP room) → last meeting notes 4. Draft follow-up — STOP, ask human to send ### 3. Pre-trade compliance check (OMS) 1. oms_check_pretrade (ticker, side, qty, limit_price) → passed/blocked + notes 2. If passed → oms_create_order (HUMAN APPROVAL required) 3. oms_list_positions → confirm position updated after fills ### 4. Capital call ILPA notice 1. fundos_get_lp → confirm LP and lp_room_id 2. Human creates CapitalCall row in /fundos/investors/{id} 3. GP clicks ILPA button → notice generated into LP room 4. Agent NEVER auto-sends LP notices ### 5. T+0 affirmation chase (HF Ops) 1. hf_ops_dtcc_list_unaffirmed → pending confirms 2. hf_ops_dtcc_get_trade_status → live state per trade 3. hf_ops_dtcc_lookup_ssi → check SSI if mismatch suspected 4. hf_ops_dtcc_get_affirmation_scorecard → COO summary --- ## Webhooks Register an HTTPS endpoint to receive real-time FundOS events. ```bash POST /api/v1/webhooks/ {"url": "https://your-server/hooks/fundos", "event_types": ["action.approval_required", "job.completed"]} ``` Events: credit.low, credit.exhausted, credit.granted, action.approval_required, action.approved, action.rejected, action.expired, job.completed, job.failed, module.enabled, module.disabled Payload signed with HMAC-SHA256 in X-FundOS-Signature header. Retry schedule: immediate → 1min → 5min → 30min → 2hr → 8hr (6 total). delivery_id is stable across retries — use it to deduplicate. Verify the signature in Python: ```python import hmac, hashlib def verify_fundos_signature(raw_body: bytes, header: str, secret: str) -> bool: expected = "sha256=" + hmac.new( secret.encode(), raw_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected.encode(), header.encode()) # In your endpoint handler: # raw = request.get_data() # sig = request.headers.get("X-FundOS-Signature", "") # if not verify_fundos_signature(raw, sig, MY_WEBHOOK_SECRET): # abort(401) ``` Webhook management endpoints: POST /api/v1/webhooks/ Register (returns secret — save it) GET /api/v1/webhooks/ List registered webhooks PATCH /api/v1/webhooks/ Update (url/name/event_types/is_active) DELETE /api/v1/webhooks/ Deactivate POST /api/v1/webhooks//rotate-secret Rotate signing secret POST /api/v1/webhooks//test Send a ping.test delivery GET /api/v1/webhooks//deliveries List delivery attempts --- ## Blog (kela.com/blog) Published articles covering fund operations, compliance, and product: - /blog/fund-intelligence-proactive-monitoring — "The questions that never get asked" — Fund Intelligence proactive monitoring; how the Monitor→Investigate→Judge→Publish pipeline works; dual-judge quality gate; finding specificity; the role of memory in fund operations monitoring. - /blog/ai-fde-fund-onboarding — "Your fund was supposed to go live six weeks ago" — AI FDE async onboarding; 30-question discovery interview; Fund Profile extraction; one-click configuration; why implementation takes months and how the AI FDE compresses it to hours. - /blog/fund-brain — "Your fund needs a brain, not more connectors" — FundOS thesis; why data access ≠ understanding; the difference between connectors and resolution. - /blog/auditor-data-room — "Your annual audit shouldn't take three weeks of email" — Auditor Data Room; ten folders auditors expect; one-click audit pack. - /blog/valuation-policy-template — "Nobody writes a valuation policy until an examiner asks for it" — SEC valuation policy requirements for private funds. - /blog/sec-exam-readiness-checklist — "You already know what the SEC will ask for" — SEC exam preparation for registered investment advisers. --- ## Error Codes 400 Bad Request — Invalid parameters 401 Unauthorized — Missing or invalid API key 403 Forbidden — Insufficient permissions 404 Not Found — Resource does not exist 422 Unprocessable — Pre-trade compliance block or validation failure 429 Too Many Requests — Rate limit (100 req/min); retry after X-RateLimit-Reset 500 Internal Error — Server error; retry with exponential backoff {"error": true, "message": "...", "code": "ERROR_CODE"} --- ## Key Facts for AI Agents - ?ephemeral=true on any POST: validates and returns shape, zero DB writes - AI processing on uploaded documents: automatic, ~30–120s; poll status - No AI model trains on or retains document content - FundOS agents propose actions; humans approve — nothing auto-executes - BYOD MCP connectors: Google Drive, SharePoint, Egnyte, QuickBooks, Salesforce, custom - OMS FIX engine: QuickFIX/n sidecar on DigitalOcean, connecting to BTIG prime brokerage - Gemini 2.5 Flash (thinkingBudget:0) powers all AI generation --- ## What's new — May 2026 ### Stateless Document API + Developer Registration (2026-05-31) A second access model for FundOS — no account setup, no fund data to configure. Five REST endpoints that accept all data inline and return completed documents. Register at https://kela.com/developers/register (email + password, 60 seconds, 30-day free trial). Get a `doc_` prefixed API key. Dashboard at https://kela.com/developers/dashboard. Endpoints and prices (all at /api/v1/documents/, Bearer doc_): POST /k1 — Schedule K-1 (Form 1065) HTML — $5/call POST /odd — ODD/DDQ completion — $25/call POST /analyze — Document red-flag + entity-map — $3/call POST /waterfall — European waterfall — free POST /pricer — IRR/MOIC/WAL — free Implementation: `app/routes/documents_api.py` + `app/services/k1_renderer.py` (pure-function K-1 renderer, no DB). Developer orgs: plan="developer", excluded from seat-fee billing, outcome fees only. Trial_active flag waives all fees. ### Compliance OS (11th module) — /fundos/compliance/ Models: ComplianceKYCRecord, FilingDeadline, RestrictedSecurity, PreClearanceRequest, ComplianceObligation, KYCNameScreenResult. Routes: - GET /fundos/compliance/ Compliance dashboard - GET /fundos/compliance/kyc/ KYC/AML records - GET /fundos/compliance/filings/ Regulatory filings - GET /fundos/compliance/trade/ Restricted securities + pre-clearance - GET /fundos/compliance/obligations/ Obligations register - POST /fundos/compliance/kyc//screen Gemini-powered name screen - POST /fundos/compliance/agent/scan Run Agent H MCP tools: fundos_list_kyc_records, fundos_list_filings, fundos_check_restricted_list (by ticker/ISIN/company name), fundos_list_obligations. ### Compliance Dashboard — /fundos/dashboard/compliance A third executive dashboard alongside GP (/fundos/dashboard/gp) and Admin (/fundos/dashboard/admin). KYC pipeline counts, expiring records in 60 days, recent name screens, upcoming filings, overdue filings list, restricted-list count, pre-clearance queue, obligations, recent Agent H runs. Safe-queries every column so a freshly-deployed DB shows zeros + a "schema not provisioned" banner instead of 500s. ### Per-user dashboard customization (persistent) Every executive dashboard supports: - Toggle widgets on/off + drag-reorder via the Customize modal (top right). - Set this dashboard as my post-login landing page (overrides /fundos/). Schema: users.allowed_dashboards CSV, users.default_dashboard, users. dashboard_prefs_json. Helpers: User.allowed_dashboards_set(), User.can_view_dashboard(key), User.dashboard_prefs(key), User.set_dashboard_prefs(key, hidden, order). Endpoints: - POST /fundos/dashboard//prefs Save widget hidden/order - POST /fundos/dashboard//default Mark as post-login landing - GET /admin/dashboard-access Admin grants per-user access ### Schema-deployment safety net When inline _migrate_db() is gated behind RUN_MIGRATIONS=1 (the default on Vercel due to DigitalOcean connection limits) and someone forgets to flip the flag, app/utils/schema_guard.py catches missing-table / column errors anywhere in the app and renders a friendly page. Superadmins get a "Run migrations now" button that calls _migrate_db() on demand via POST /superadmin/run-migrations. ### Sanity portfolio sync GET /superadmin/sanity-sync (dry-run preview) and POST /superadmin/sanity-sync (apply) push the FundOS portfolio for org=SANITY_SYNC_ORG_ID into the public Sanity CMS that backs eight-capital.com. The sync collapses VI follow-on rows ("Foo (FO)") to a single canonical company, only patches fields it owns (name, status, batch), and never touches hand-curated Sanity fields (description, logo, founder bios). Re-running is safe (createIfNotExists + targeted patches); deletes and renames are never automatic — orphans on the site are surfaced for manual reconciliation in Sanity Studio. Implementation: app/services/sanity_sync.py. ### Per-page "How to use" help Every FundOS page now has a small ? button in the top-right corner that opens a modal with page-specific help (also accessible via the ? key). Coverage is seeded for ~20 high-traffic pages. Registry lives in app/utils/page_help.py — adding help for a new page is one tuple entry. ### Admin module access bypass @module_required now lets admins / superadmins bypass both gates (the per-user enabled_modules layer AND the org-subscription layer). Non- admin users still hit both. Rationale: admins make billing decisions and shouldn't be blocked from clicking into a module they're about to subscribe to. ### Operator CLI — `fundos` (May 2026) Standalone Python CLI for operator workflows. Lives in cli/ in the repo. pip install -e ./cli fundos login # prompts for API key + base URL fundos whoami # identity check Command tree: fundos org list / get / create / enable-vertical / cleanup-spam fundos credits balance / history / add fundos fix status / config / connect / test-order / fills fundos db status / migrate / seed fundos mcp tools / call # read-only tools only fundos logs audit / agents / errors (all --org-id filter) The CLI talks HTTP only — no DB access, no app/ imports. Backend at /api/cli/* (18 routes). Same Bearer-token auth as /api/v1/*. Both the CLI and the server defensively strip an accidental "Bearer " prefix from pasted tokens, so the most common copy-paste 401 doesn't happen. On a 401, the CLI prints the redacted key prefix + base URL so users can spot env-mismatches (dev key against prod, etc.). Env vars: FUNDOS_API_KEY, FUNDOS_BASE_URL (default https://www.kela.com). ### Try-before-you-pay billing (auth-then-capture, May 2026) For packaged AI tasks (ODD, CIM, audit pack, K-1 generation, Level 3 valuation memos), credits are reserved when the task runs but not charged until the customer uses the output. Promise to the customer: "View any AI-generated artifact for free. We only charge if you download it, accept it, or feed it into another tool. If 7 days pass without confirmation, the hold expires and you're not charged." State machine on CreditLedger.hold_status: pending — task done, output viewable, NOT counted toward balance confirmed — customer used the output (download / explicit confirm / chained tool call); charge stands refunded — customer rejected the output; no charge expired — 7 days elapsed with no action; no charge REST API (Bearer auth): GET /api/v1/tasks/holds/ list pending for org GET /api/v1/tasks/holds/ read a hold's state POST /api/v1/tasks/holds//confirm customer accepts the charge POST /api/v1/tasks/holds//refund customer rejects the output POST /api/v1/tasks/holds/cron/expire hourly cron (CRON_SECRET) Document download gate: any Document whose billing_hold_id points at a pending hold auto-confirms on download; a refunded or expired hold returns 402 with structured JSON `{error, hold_id, hold_status}`. Schema columns (auto-migrated unconditionally on every cold start — not gated by RUN_MIGRATIONS, because the ORM SELECTs these on every Document query and missing them would 500 every page that loads docs): credit_ledger.hold_status VARCHAR(20) credit_ledger.hold_expires_at TIMESTAMP documents.billing_hold_id INTEGER (FK credit_ledger.id) ### Anti-spam signup guards (May 2026) Every signup path runs three independent checks at app/utils/signup_guard.py: 1. Disposable-email blocklist (17 domains: mailinator, guerrillamail, tempmail, sharklasers, dispostable, maildrop, …). yopmail.com is explicitly whitelisted in ALLOWED_TEST_DOMAINS for internal QA. 2. Random-name detector — two complementary heuristics: - vowel ratio < 0.20 on the cleaned (letters-only) string - ≥ 3 lower→upper case transitions The second heuristic catches high-vowel bot strings like "HrzIIXAEjlmnTIuDjgAu" (40% vowels) that vowel-ratio alone can't. Tested against the full Eight Capital / VantedgeAI / Bristol Myers Squibb / PricewaterhouseCoopers corpus — zero false positives. 3. IP rate limit — 5 attempts per IP per hour, Postgres-backed, fails open on DB hiccups so legit signups are never blocked by infra. Wired into POST /signup, POST /create-org, and the new-user branch of the Google OAuth callback. Returns HTML errors for browser submits and JSON 400s for the API path. Cleanup of existing spam: POST /api/cli/admin/cleanup-spam-orgs (or `fundos org cleanup-spam` from the CLI). Defaults to dry-run. Six nested safety guards: - PROTECTED_ORG_IDS (= {1, 2, 17, 30}) never touched - PROTECTED_EMAIL_DOMAINS (yopmail.com) never touched - already-suspended orgs not re-suspended - paid plans not touched (only free / starter / NULL) - orgs < 24h old not touched - orgs with any Document / DealRoom / Deal rows not touched (real work) Then matches at least one spam signal (random-string name, dotted-bot name, disposable-email owner) before flipping status='suspended' and writing an AuditLog row. ### Billing engine — outcome fees, add-ons, invoicing (May 2026) Metering: every REST (/api/v1/tools//call) and MCP Bearer tool call deducts credits from the org's CreditLedger; insufficient balance returns a 402 with required/balance/topup_url. Suspended orgs are blocked at the meter. Outcome fees: packaged deliverables carry a success-only fee — ODD $150, CIM $250, Diligence Agent $200, valuation memo $75, valuation policy $200, K-1 $50, audit pack $100, contract $15, redaction $25. Resolution chain: trial-waived → CFO Center inclusion → per-org override → superadmin-edited global price → hardcoded default. All editable in the superadmin UI with no deploy. Add-on modules (per org/month): CFO Center $999 (incl. 10 K-1s + 4 audit packs + 1 valuation policy/yr), HF Ops + OMS $1,499, Auditor Suite $199, Compliance OS $149, API + MCP $149 — editable in superadmin. Monthly crons (CRON_SECRET bearer, defined in vercel.json): 06:00 1st /billing/cron/push-stripe-monthly — seat fee + overage to Stripe 07:00 1st /billing/cron/grant-monthly-credits — seats × grant CreditLedger topup 08:00 1st /billing/cron/generate-invoices — paper invoices (invoice-pay orgs) 08:00 dly /billing/cron/send-reminders — overdue reminders 09:00 dly /billing/cron/dunning — 30d past_due / 60d suspend / 90d terminate Annual prepay: org admins self-serve "Switch to Annual" from /billing/ (default 20% off / 2 months free); superadmin can issue prepay invoices. Tax/VAT: per-org tax_rate_pct on paper invoices; Stripe Tax (automatic_tax) on all Stripe Checkout flows. Credit notes + manual wire/ACH/check payment recording on invoices. Invoice PDFs render domestic + international-USD + FX-via-intermediary wire instructions, ACH, and check details from the superadmin-editable BillingSettings (/superadmin/billing/payment-settings). Internal team reference: /superadmin/billing/reference. ## Fund Intelligence — Proactive AI Monitoring (June 2026) Proactive monitoring system that automatically surfaces compliance deadlines, overdue capital calls, KYC expirations, cash shortfalls, and LP communication gaps before they become crises — without requiring any manual input from the GP. Dashboard: GET /fundos/monitoring/ — module health grid, 7-day trend, last run status. Daily brief: GET /fundos/monitoring/brief/ — all findings for that date. PIPELINE: Monitor → Investigate → Judge → Publish runs daily at 6am UTC. 1. Monitor: SQL queries against live fund tables for 5 signal types: - compliance_filing_deadline: filings due within 14 days - compliance_kyc_expiry: KYC records expiring within 30 days - lp_overdue_call: capital calls past due_date (critical >7d, high >3d) - lp_communication_gap: LPs with no email for 90+ days - cfo_cash_low: fund cash balance < 110% of minimum 2. Investigate: Gemini root-causes each candidate, queries prior memory (has this entity been flagged before? was it actioned?), returns {title, severity, summary, root_cause, recommendation, affected_entities, confidence} 3. Judge: Two independent Gemini passes; finding passes only if BOTH approve AND combined confidence >= 0.65. Filters noise before reaching the GP. 4. Publish: Approved findings write FundMonitoringPublished row + update FundDailyBrief. Critical/HIGH trigger admin email. FINDING CARD: title, severity badge, summary, collapsible root_cause + recommendation + affected_entities list. Action buttons: "Mark resolved" + "Snooze 2 days". MEMORY: fund_finding_memory tracks per-entity flag count, first/last seen, resolution status. Investigation prompt includes this so Gemini adjusts confidence for recurrent unresolved issues. API routes (all Bearer auth): GET /api/v1/monitoring/brief/today Today's brief JSON GET /api/v1/monitoring/brief/ Brief for a specific date GET /api/v1/monitoring/findings All findings (filters: status, severity, module) GET /api/v1/monitoring/findings/ Single finding detail POST /api/v1/monitoring/findings//action Mark as actioned/resolved POST /api/v1/monitoring/findings//snooze Snooze for N days GET /api/v1/monitoring/watches Custom watches POST /api/v1/monitoring/watches Create a watch DELETE /api/v1/monitoring/watches/ Delete a watch POST /api/v1/monitoring/run Trigger a manual run (admin) GET /api/v1/monitoring/run//status Poll background run status SCHEDULER (non-Vercel only): monitoring_daily: cron 6am UTC — full pipeline for all orgs monitoring_critical: interval 30min — critical signal types only monitoring_baselines: cron Sunday 2am UTC — recalculate baselines DB TABLES: fund_monitoring_runs, fund_monitoring_watches, fund_monitoring_candidates, fund_monitoring_findings, fund_monitoring_judgments, fund_monitoring_published, fund_daily_briefs, fund_monitoring_baselines, fund_finding_memory POST-DEPLOY: /superadmin → Run migrations now (creates 9 new tables). ## Links Homepage: https://kela.com Developer API: https://kela.com/developers (stateless API landing — no login required) Developer Register: https://kela.com/developers/register (get a doc_ key in 60 seconds) Developer Platform: https://kela.com/developer (logged-in power-tools hub, plan-gated) API Docs: https://kela.com/api/docs MCP Info: https://www.kela.com/mcp/info CLAUDE.md: https://kela.com/CLAUDE.md llms.txt: https://kela.com/llms.txt llms-full.txt: https://kela.com/llms-full.txt (this document) FAQ (JSON-LD): https://kela.com/faq.json (12 Q&As, schema.org FAQPage) FAQ (HTML): https://kela.com/faq AX Benchmark: https://kela.com/ax (agent-readability results, updated monthly) Privacy: https://kela.com/privacy Trust: https://vantedgeai.trust.site/ fundos-mcp repo: https://github.com/8vdx1/fundos-mcp ## Agent Experience (AX) Benchmark FundOS publishes a self-hosted, reproducible benchmark that measures whether an AI agent given ONLY the FundOS documentation can correctly identify the right MCP tool, avoid hallucinating non-existent tools, and flag write actions as needing human approval. Run: 40 tasks × 8 categories (MCP/Auth, Deal CRM, LP/Investors, VDR/Documents, Risk, CFO/Finance, Agents, Webhooks) Latest score: 40/40 correct | 0 hallucinations | 80/80 score | 100% approval gate coverage Model: gemini-2.5-flash (seeded run); harness runs claude-sonnet-4-5 via Anthropic API Public results: https://kela.com/ax Open source harness: https://github.com/8vdx1/fundos-mcp (benchmarks/ax/) Run yourself: pip install anthropic pyyaml && python benchmarks/ax/runner.py Scoring: 2pts = correct answer + approval gate mentioned (or not required) 1pt = correct tool but missed the human-approval warning 0pts = wrong answer or hallucinated tool/endpoint Reproducibility: every task definition, scoring function, and result file is in the public repo. The benchmark is intentionally self-authored — it is FundOS's measure of its own documentation quality, not a third-party evaluation.