API v1

API docs for funds and fund administrators

This API is designed for high-volume funds and fund administrators.

Quickstart 1: Get your API key
Generate keys in Settings → API. Key values display once.
Authorization: Bearer fip_live_...
Quickstart 2: Download report PDF
Download a filing report for a firm and reporting year.
curl -L -H "Authorization: Bearer $API_KEY" \
  -o ca-vcc-report.pdf \
  "https://www.fipvcc.com/api/v1/firms/{firmId}/report?year=2025"

Management API Reference

This document defines the public management API under /api/v1/ for high-volume funds and fund administrators.

Base URL and Version

  • Base path: /api/v1/
  • Versioning: path versioning (v1)

Authentication and Authorization

  • Auth mode: API key
  • Header: Authorization: Bearer <api_key>
  • API keys are user-scoped and inherit that user's firm access
  • Firm on the API key must be on the enterprise plan
  • Role rules:
    • admin: read and write
    • member: read-only
  • Common auth/permission responses:
    • 401 missing or invalid API key
    • 402 payment required (firm is not on enterprise plan)
    • 403 key is valid but does not have required access
    • 404 resource is not in caller scope

Basic Firm Management

The Basic Notes

  • Every firm is isolated in API scope.
  • Callers only see firms they are authorized to access.
  • firmId is the required scope key for firm-level operations.
  • Report PDFs are downloaded with GET /api/v1/firms/{firmId}/report?year=YYYY.

VC Investment Definition (isVcInvestment)

isVcInvestment follows the legal definition incorporated by California FIP-VCC.

  • Cal. Corp. Code section 27500(h) incorporates 10 CCR section 260.204.9(a)(5).
  • 10 CCR section 260.204.9(a)(5): a "venture capital investment" is an acquisition of securities in an operating company where the investment adviser, advised entity, or an affiliated person has or obtains management rights (as defined in 10 CCR section 260.204.9(a)(7)).
  • Set isVcInvestment to false for deals that do not meet this definition. These records are excluded from VC-only readiness and filing calculations.

Firm Management for Fund Administrators

Concept: External Reference ID

externalReferenceId is an optional caller-provided identifier for matching a firm in your internal system.

Rules:

  • Use a stable, unique value from your system (example: CRM org ID).
  • Do not include sensitive personal data.
  • Treat this as an idempotency-friendly mapping key for retries and reconciliation.

Create Firm

POST /api/v1/firms

Request body:

{
  "name": "Acme Ventures",
  "website": "https://acme.vc",
  "headquartersLocation": "San Francisco, CA",
  "externalReferenceId": "crm_firm_93214"
}

Successful response (201):

{
  "firm": {
    "id": "firm_123",
    "name": "Acme Ventures",
    "website": "https://acme.vc",
    "headquartersLocation": "San Francisco, CA",
    "externalReferenceId": "crm_firm_93214",
    "createdAt": "2026-02-12T00:00:00.000Z"
  }
}

Validation notes:

  • name is required.
  • externalReferenceId should be unique within your tenant context.
  • Return 409 when a duplicate mapping key is submitted.
  • On successful create, the API key's firm is recorded as the service provider for the new firm.

API Reference

The endpoints below cover the public /api/v1 surface.

Common Headers

Use these headers unless an endpoint says otherwise.

HeaderRequiredValue
AuthorizationYesBearer <api_key>
Content-TypeFor POST requestsapplication/json
AcceptRecommendedapplication/json

1. List Firms

GET /api/v1/firms

Purpose: list firms accessible to the authenticated key.

Sample request:

curl -H "Authorization: Bearer $API_KEY" \
  "$BASE_URL/api/v1/firms"

Sample response (200):

{
  "firms": [
    {
      "id": "firm_123",
      "name": "Acme Ventures",
      "website": "https://acme.vc",
      "headquartersLocation": "San Francisco, CA",
      "externalReferenceId": "crm_firm_93214",
      "createdAt": "2026-02-12T00:00:00.000Z"
    }
  ]
}

2. Create Firm

POST /api/v1/firms

Purpose: create a firm workspace.

Required headers:

  • Authorization: Bearer <api_key>
  • Content-Type: application/json

Sample request:

curl -X POST "$BASE_URL/api/v1/firms" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Ventures",
    "website": "https://acme.vc",
    "headquartersLocation": "San Francisco, CA",
    "externalReferenceId": "crm_firm_93214"
  }'

Sample response (201):

{
  "firm": {
    "id": "firm_123",
    "name": "Acme Ventures",
    "website": "https://acme.vc",
    "headquartersLocation": "San Francisco, CA",
    "externalReferenceId": "crm_firm_93214",
    "createdAt": "2026-02-12T00:00:00.000Z"
  }
}

3. List Funds

GET /api/v1/firms/{firmId}/funds

Purpose: list funds in a firm.

Sample request:

curl -H "Authorization: Bearer $API_KEY" \
  "$BASE_URL/api/v1/firms/firm_123/funds"

Sample response (200):

{
  "funds": [
    {
      "id": "fund_456",
      "firmId": "firm_123",
      "name": "Acme Opportunity Fund I",
      "isCoveredEntity": true,
      "legalName": "Acme Opportunity Fund I, L.P.",
      "pointOfContactEmail": "[email protected]",
      "designatedEmail": "[email protected]",
      "website": "https://acme.vc",
      "createdAt": "2026-02-12T00:00:00.000Z"
    }
  ]
}

4. Create Fund

POST /api/v1/firms/{firmId}/funds

Purpose: create a fund under a firm.

Required headers:

  • Authorization: Bearer <api_key>
  • Content-Type: application/json

Sample request:

curl -X POST "$BASE_URL/api/v1/firms/firm_123/funds" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Opportunity Fund I",
    "isCoveredEntity": true,
    "legalName": "Acme Opportunity Fund I, L.P.",
    "pointOfContactName": "Jane Doe",
    "pointOfContactTitle": "COO",
    "pointOfContactEmail": "[email protected]",
    "designatedEmail": "[email protected]",
    "designatedPhone": "+1-555-555-5555",
    "designatedAddress": "123 Main St, San Francisco, CA",
    "website": "https://acme.vc"
  }'

Sample response (201):

{
  "fund": {
    "id": "fund_456",
    "firmId": "firm_123",
    "name": "Acme Opportunity Fund I",
    "isCoveredEntity": true,
    "legalName": "Acme Opportunity Fund I, L.P.",
    "pointOfContactEmail": "[email protected]",
    "designatedEmail": "[email protected]",
    "createdAt": "2026-02-12T00:00:00.000Z"
  }
}

5. List Portfolio Companies

GET /api/v1/firms/{firmId}/portcos

Purpose: list portfolio companies for a firm.

Query params:

  • year optional, defaults to prior calendar year
  • fundId optional fund filter

Response object schema (Portco):

FieldTypeNotes
idstringPortfolio company ID
firmIdstringFirm scope ID
fundIdstringFund ID
reportingYearintegerReporting year
legalNamestringCompany legal name
principalPlaceOfBusinessstringPrincipal place of business
amountInvestedUsdCentsintegerInvestment amount in USD cents
isVcInvestmentbooleanWhether the deal is treated as a VC investment under the legal definition above
foundersTotalKnownbooleanWhether total founders count is known
foundersTotalinteger | nullFounder count; may be null when unknown
createdAtISO 8601 stringCreation timestamp
updatedAtISO 8601 stringLast update timestamp

Sample request:

curl -H "Authorization: Bearer $API_KEY" \
  "$BASE_URL/api/v1/firms/firm_123/portcos?year=2025"

Sample response (200):

{
  "portcos": [
    {
      "id": "portco_789",
      "firmId": "firm_123",
      "fundId": "fund_456",
      "reportingYear": 2025,
      "legalName": "Example Labs Inc.",
      "principalPlaceOfBusiness": "San Francisco, CA",
      "amountInvestedUsdCents": 5000000,
      "isVcInvestment": true,
      "foundersTotalKnown": true,
      "foundersTotal": 2,
      "createdAt": "2026-02-12T00:00:00.000Z",
      "updatedAt": "2026-02-12T00:00:00.000Z"
    }
  ]
}

6. Create Portfolio Company

POST /api/v1/firms/{firmId}/portcos

Purpose: create a portfolio company row for a reporting year.

Required headers:

  • Authorization: Bearer <api_key>
  • Content-Type: application/json

Request body schema:

FieldTypeRequiredNotes
fundIdstringNoDefaults to first accessible fund if omitted
reportingYearintegerYes2000 to 2100
legalNamestringYesNon-empty
principalPlaceOfBusinessstringYesNon-empty
amountInvestedUsdCentsintegerYesMinimum 0
isVcInvestmentbooleanNoDefaults to true
foundersTotalKnownbooleanNoDefaults to true
foundersTotalintegerConditionallyRequired when foundersTotalKnown is true; otherwise omitted

Sample request:

curl -X POST "$BASE_URL/api/v1/firms/firm_123/portcos" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fundId": "fund_456",
    "reportingYear": 2025,
    "legalName": "Example Labs Inc.",
    "principalPlaceOfBusiness": "San Francisco, CA",
    "amountInvestedUsdCents": 5000000,
    "isVcInvestment": true,
    "foundersTotalKnown": true,
    "foundersTotal": 2
  }'

Sample response (201):

{
  "portco": {
    "id": "portco_789",
    "firmId": "firm_123",
    "fundId": "fund_456",
    "reportingYear": 2025,
    "legalName": "Example Labs Inc.",
    "principalPlaceOfBusiness": "San Francisco, CA",
    "amountInvestedUsdCents": 5000000,
    "isVcInvestment": true,
    "foundersTotalKnown": true,
    "foundersTotal": 2,
    "createdAt": "2026-02-12T00:00:00.000Z",
    "updatedAt": "2026-02-12T00:00:00.000Z"
  }
}

7. Add Team Member

POST /api/v1/firms/{firmId}/team-members

Purpose: add a team member to a firm.

Required headers:

  • Authorization: Bearer <api_key>
  • Content-Type: application/json

Sample request:

curl -X POST "$BASE_URL/api/v1/firms/firm_123/team-members" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "name": "GP Name",
    "role": "member",
    "sendInviteEmail": true
  }'

Sample response (201):

{
  "teamMember": {
    "id": "team_member_123",
    "userId": "user_123",
    "email": "[email protected]",
    "name": "GP Name",
    "role": "member",
    "status": "active",
    "createdAt": "2026-02-12T00:00:00.000Z"
  }
}

8. Remove Team Member

DELETE /api/v1/firms/{firmId}/team-members/{teamMemberId}

Purpose: remove a team member from a firm.

Sample request:

curl -X DELETE \
  -H "Authorization: Bearer $API_KEY" \
  "$BASE_URL/api/v1/firms/firm_123/team-members/team_member_123"

Sample response (200):

{
  "deletedTeamMemberId": "team_member_123"
}

9. Get Year Readiness

GET /api/v1/firms/{firmId}/year-readiness?year=YYYY

Purpose: return filing readiness status and blockers for a firm-year.

Sample request:

curl -H "Authorization: Bearer $API_KEY" \
  "$BASE_URL/api/v1/firms/firm_123/year-readiness?year=2025"

Sample response (200):

{
  "readiness": {
    "firmId": "firm_123",
    "year": 2025,
    "status": "BLOCKED",
    "blockers": [
      "No covered funds marked for reporting.",
      "Missing point of contact email for one or more covered funds."
    ],
    "defaultSubmissionLink": "https://compliance.fipvcc.com/survey/abc123",
    "counts": {
      "funds": 3,
      "coveredFunds": 2,
      "portcos": 14,
      "portcosWithResponses": 10
    }
  }
}

10. Download Report PDF

GET /api/v1/firms/{firmId}/report?year=YYYY

Purpose: download the combined filing report PDF.

Required headers:

  • Authorization: Bearer <api_key>
  • Accept: application/pdf recommended

Sample request:

curl -L \
  -H "Authorization: Bearer $API_KEY" \
  -H "Accept: application/pdf" \
  -o "firm_123-2025-ca-vcc-report.pdf" \
  "$BASE_URL/api/v1/firms/firm_123/report?year=2025"

Successful response:

  • Status: 200
  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename="firm_123-2025-ca-vcc-report.pdf"

Blocker response (409):

{
  "error": "Report generation is blocked until readiness blockers are resolved."
}

Error Shape

Sample JSON error response:

{
  "error": "Human readable message",
  "code": "OPTIONAL_MACHINE_CODE"
}

Example payment-required response (402):

{
  "error": "Payment required. API access is only available on the enterprise plan.",
  "code": "PAYMENT_REQUIRED"
}