Ekvi · API reference · version 1.0.0

Ekvi API

Cap tables, option plans and dilution for Cyprus companies, as an event ledger.

Machine-readable schema (OpenAPI 3.1.0): /api/v1/openapi.json. Version 1.0.0; a breaking change gets a new versioned path and this one keeps answering.

Overview

The Ekvi API reads and writes a company's share register as an append-only ledger of events. Every projection — the register of members, vesting, option pools, an IFRS 2 schedule — is computed from the events on or before a date, so the same request with the same as_of always answers the same.

Writes go through exactly the same capital rules as the portal's forms: an allotment above the authorised capital, a transfer of more shares than the holder has, an exercise above what has vested — each is refused with 409 and the rule's stable name, and nothing is written. A recorded event is never edited; a correction is a new event.

Amounts are decimal strings ("1250.00"), share counts are integers, dates are ISO (YYYY-MM-DD).

Authentication

Every request except GET /health carries a bearer token:

Authorization: Bearer <token>

Creating a token. Sign in to the portal, open Profile → API tokens (/app/profile#api-tokens), give the token a name and confirm with your password (an account without a password confirms by having signed in within the last few minutes). The token is shown once; Ekvi stores only its SHA-256 and cannot show it again. Revoke it on the same page. On an on-prem installation the administrator can also issue one from the command line: python -m ekvi.store.admin issue-token <user_id> <label>.

What a token may do. A token acts as the person it belongs to, with that person's role in each company: an *admin* records events; a *viewer* or *auditor* reads every projection; an *employee* reads only their own rows in the portal and gets 403 from the whole-company endpoints here. Each company is isolated twice — by the path and by row-level security in the database — so a token can never read a company its owner is not a member of (404, which does not say whether the company exists).

A token created on the profile page opens the API only, not the portal, and changing your password revokes it. Keep it like a password.

Errors

StatusBodyWhen
401ErrorOutNo Authorization header, a header that is not Bearer …, or a token that is unknown, revoked, or belongs to a disabled account.
403ErrorOutYour role in this company does not allow the request (a viewer posting an event, an employee reading the whole register), or the company is archived or read-only.
404ErrorOutThe company or fund does not exist or you are not a member of it — deliberately indistinguishable.
409GuardRefusalOutA named capital rule refused the request: {"detail": {"guard": "...", "detail": "..."}}. Branch on guard. A duplicate event key is unique_event_key. Nothing was recorded.
413ErrorOutThe JSON body is larger than the API accepts.
422ErrorOut or ValidationErrorOutThe body is not a JSON object, names an unknown event type or field, misses a required field, or a query parameter is not a valid date.
429ErrorOutA daily limit was reached (creating funds).

Companies

The companies you are a member of.

GET /companies

List your companies

Every company the token's owner is a member of, with their role in each. Funds are listed separately at GET /funds.

Responses

StatusBodyMeaning
200array of CompanyOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.

Example 200 response

[
  {
    "id": "co-lefkara",
    "name": "Lefkara Robotics Ltd",
    "role": "admin"
  }
]

Ledger

The append-only event ledger of a company: read it, append to it.

GET /companies/{company_id}/events

Read the event ledger

Every event recorded for the company, in ledger order, in exactly the shape POST accepts — the ledger is the source of truth and every projection is computed from it. Readers only (admin, viewer, auditor); an employee gets 403.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.

Responses

StatusBodyMeaning
200array of one of the event types belowEvery event of the company in ledger order, each in the shape POST accepts.
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
422ValidationErrorOutValidation Error

Example 200 response

[
  {
    "type": "ShareClassDefined",
    "date": "2025-01-15",
    "class_id": "common",
    "name": "Ordinary",
    "kind": "common",
    "authorized": 10000,
    "nominal_value": "1.00"
  },
  {
    "type": "Allotment",
    "date": "2025-02-01",
    "event_id": "A-2025-01",
    "holder_id": "andreas",
    "class_id": "common",
    "quantity": 3500,
    "price_per_share": "1.00"
  }
]

POST /companies/{company_id}/events

Record an event

Append one event to the company's ledger. The event is checked against every capital rule — the same guards the portal's forms use — on the register as it stands with this event added; a refusal answers 409 with the rule's name and records nothing. Admins only. Event ids are yours to choose and unique per company, which makes a retry safe: the second POST of the same event answers 409 unique_event_key instead of recording it twice.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.

Request body

one of the event types below — see Event types

Example: ShareClassDefined

{
  "type": "ShareClassDefined",
  "date": "2025-01-15",
  "class_id": "common",
  "name": "Ordinary",
  "kind": "common",
  "authorized": 10000,
  "nominal_value": "1.00"
}

Example: HolderRecorded

{
  "type": "HolderRecorded",
  "date": "2025-01-15",
  "event_id": "h-andreas-1",
  "holder_id": "andreas",
  "kind": "natural_person",
  "legal_name": "Andreas Christofi",
  "capacity": "own_account",
  "address": "12 Makariou Ave, 1065 Nicosia, Cyprus"
}

Example: Allotment

{
  "type": "Allotment",
  "date": "2025-02-01",
  "event_id": "A-2025-01",
  "holder_id": "andreas",
  "class_id": "common",
  "quantity": 3500,
  "price_per_share": "1.00"
}

Responses

StatusBodyMeaning
201EventRecordedSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
409GuardRefusalOutRefused by a named capital rule; nothing was recorded.
413ErrorOutThe JSON body exceeds the size the API accepts.
422ErrorOutThe body is not a valid event: unknown type, unknown or missing field, bad value.

Example 201 response

{
  "event_key": "A-2025-01",
  "event_type": "Allotment",
  "seq": 42
}

Projections

What the ledger says on a date: register, vesting, pools.

GET /companies/{company_id}/register

Register of members on a date

The register projected from the events on or before as_of (default today): one line per holder with shares, options, stakes and the s.105 particulars, plus the instruments (ASAs, convertibles) that are not shares until they convert. Readers only.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.
as_ofquerystring (date) or nullnoProjection date, ISO; defaults to today

Responses

StatusBodyMeaning
200RegisterOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
422ValidationErrorOutThe body or a parameter could not be read.

Example 200 response

{
  "as_of": "2026-10-12",
  "company_id": "co-lefkara",
  "fully_diluted": 5000,
  "instruments": [],
  "instruments_total": "0",
  "lines": [
    {
      "address": "12 Makariou Ave, 1065 Nicosia, Cyprus",
      "consideration_recorded": "3500.00",
      "date_entered": "2025-02-01",
      "holder_id": "andreas",
      "kind": "natural_person",
      "legal_name": "Andreas Christofi",
      "options": 0,
      "outstanding": 3500,
      "pct_fully_diluted": "70.0000",
      "pct_outstanding": "77.7778"
    }
  ],
  "total_options": 500,
  "total_outstanding": 4500
}

GET /companies/{company_id}/vesting

Option vesting on a date

Every option grant with what has vested, been exercised, cancelled or lapsed on as_of (default today). Readers only.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.
as_ofquerystring (date) or nullnoProjection date, ISO; defaults to today

Responses

StatusBodyMeaning
200array of VestingLineOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
422ValidationErrorOutThe body or a parameter could not be read.

Example 200 response

[
  {
    "cancelled": 0,
    "exercisable": 120,
    "exercised": 0,
    "fmv_at_grant": "1.50",
    "grant_id": "G-1",
    "holder_id": "eleni",
    "lapsed": 0,
    "outstanding": 480,
    "plan_id": "esop-2025",
    "quantity": 480,
    "valuation_at_grant": "val-2025",
    "vested": 120
  }
]

GET /companies/{company_id}/pools

Option pools on a date

Each option plan's pool on as_of (default today): size, granted, exercised, available. Readers only.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.
as_ofquerystring (date) or nullnoProjection date, ISO; defaults to today

Responses

StatusBodyMeaning
200array of PoolLineOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
422ValidationErrorOutThe body or a parameter could not be read.

Example 200 response

[
  {
    "available": 520,
    "exercised": 0,
    "granted": 480,
    "plan_id": "esop-2025",
    "pool_size": 1000
  }
]

Modelling

Read-only calculations: a round, an IFRS 2 schedule.

POST /companies/{company_id}/rounds/model

Model a funding round

Model a round on the register at as_of (default today): price, pool top-up, instrument conversions, anti-dilution, the dilution table and the events that would make it real. Nothing is recorded, so readers may call it; recording the proposed events is a separate POST /events by an admin. 422 for terms that cannot be read, 409 with the guard name for a round the rules refuse.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.
as_ofquerystring (date) or nullnoProjection date, ISO; defaults to today

Request body

object

Example

{
  "round_id": "seed",
  "name": "Seed",
  "kind": "seed",
  "date": "2026-10-12",
  "pre_money": "2000000",
  "class_id": "common",
  "subscriptions": [
    {
      "holder_id": "fund-x",
      "amount": "500000"
    }
  ]
}

Responses

StatusBodyMeaning
200RoundModelOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
409GuardRefusalOutRefused by a named capital rule; nothing was recorded.
422ErrorOutThe body is not a valid event: unknown type, unknown or missing field, bad value.

Example 200 response

{
  "adjustments": [],
  "as_of": "2026-10-12",
  "capitalization_post": "6250",
  "company_id": "co-lefkara",
  "conversions": [],
  "dilution": [
    {
      "after": "3500",
      "before": "3500",
      "key": "andreas",
      "kind": "holder",
      "pct_after": "56.0000",
      "pct_before": "70.0000"
    }
  ],
  "new_money": "500000",
  "pool_pct_post": "8.0000",
  "pool_top_up": 0,
  "post": {
    "capitalization": "6250",
    "fully_diluted": 6250,
    "instruments_total": "50000",
    "total_options": 500,
    "total_outstanding": 5750
  },
  "post_money_implied": "2500000",
  "pre": {
    "capitalization": "5000",
    "fully_diluted": 5000,
    "instruments_total": "50000",
    "total_options": 500,
    "total_outstanding": 4500
  },
  "price": "400.00",
  "price_exact": "400",
  "pricing_capitalization": "5000",
  "proposed_events": [
    {
      "class_id": "common",
      "date": "2026-10-12",
      "event_id": "seed-fund-x",
      "holder_id": "fund-x",
      "price_per_share": "400.00",
      "quantity": 1250,
      "round_id": "seed",
      "type": "Allotment"
    }
  ],
  "round_id": "seed",
  "shares_issued": 1250,
  "subscriptions": [
    {
      "amount": "500000",
      "holder_id": "fund-x",
      "paid": "500000.00",
      "remainder": "0.00",
      "shares": 1250
    }
  ]
}

GET /companies/{company_id}/ifrs2

IFRS 2 expense schedule

The share-based payment expense for the period from–to (graded-vesting attribution, reversal on forfeiture). Grants without a recorded fair value are listed with their status and left out of the total — never given a guessed value. 409 guard_period for an inverted period. Readers only.

Parameters

NameInTypeRequiredDescription
company_idpathstringyesThe company's id, as GET /companies lists it.
fromquerystring (date)yesPeriod start, ISO
toquerystring (date)yesPeriod end, ISO

Responses

StatusBodyMeaning
200ExpenseReportOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
409GuardRefusalOutRefused by a named capital rule; nothing was recorded.
422ValidationErrorOutThe body or a parameter could not be read.

Example 200 response

{
  "company_id": "co-lefkara",
  "complete": true,
  "excluded_grants": 0,
  "lines": [
    {
      "cumulative_end": "190.00",
      "cumulative_start": "100.00",
      "expense": "90.00",
      "fair_value_per_option": "0.90",
      "forfeited_unvested": 0,
      "grant_id": "G-1",
      "holder_id": "eleni",
      "method": "black_scholes",
      "plan_id": "esop-2025",
      "quantity": 480,
      "remaining": "242.00",
      "reversed": "0.00",
      "status": "ok",
      "total_fair_value": "432.00"
    }
  ],
  "period_end": "2026-06-30",
  "period_start": "2026-01-01",
  "total_expense": "90.00"
}

Funds

Funds you are a member of and their own ledger.

GET /funds

List your funds

Every fund the token's owner is a member of, with their role in each.

Responses

StatusBodyMeaning
200array of CompanyOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.

Example 200 response

[
  {
    "id": "co-lefkara",
    "name": "Lefkara Robotics Ltd",
    "role": "admin"
  }
]

POST /funds

Create a fund

Create a fund; the caller becomes its admin. 403 for an account that may not create one, 429 at the daily limit per user.

Request body

FundIn

Responses

StatusBodyMeaning
201CompanyOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
422ValidationErrorOutThe body or a parameter could not be read.
429ErrorOutA daily limit was reached.

Example 201 response

{
  "id": "co-lefkara",
  "name": "Lefkara Robotics Ltd",
  "role": "admin"
}

GET /funds/{fund_id}/events

Read a fund's ledger

The fund's events the caller may read: the whole ledger for an admin, viewer or auditor; for a limited partner, its own rows and the fund-wide rows partners may see.

Parameters

NameInTypeRequiredDescription
fund_idpathstringyesThe fund's id, as GET /funds lists it.

Responses

StatusBodyMeaning
200array of objectThe fund's events the caller may read, in ledger order.
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
422ValidationErrorOutValidation Error

Example 200 response

[
  {
    "type": "LpAdmitted",
    "date": "2026-01-10",
    "lp_id": "lp-a",
    "legal_name": "Kyrenia Family Office Ltd",
    "kind": "legal_entity",
    "partner_role": "lp",
    "commitment": "1000000"
  }
]

POST /funds/{fund_id}/events

Record a fund event

Record one fund event. A capital call or distribution is written together with one allocation line per partner; 409 with the guard's name for a refusal. Admins only.

Parameters

NameInTypeRequiredDescription
fund_idpathstringyesThe fund's id, as GET /funds lists it.

Request body

one of the event types below — see Event types

Example: LpAdmitted

{
  "type": "LpAdmitted",
  "date": "2026-01-10",
  "lp_id": "lp-a",
  "legal_name": "Kyrenia Family Office Ltd",
  "kind": "legal_entity",
  "partner_role": "lp",
  "commitment": "1000000"
}

Responses

StatusBodyMeaning
201FundRecordedOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
409GuardRefusalOutRefused by a named capital rule; nothing was recorded.
413ErrorOutThe JSON body exceeds the size the API accepts.
422ErrorOutThe body is not a valid event: unknown type, unknown or missing field, bad value.

Example 201 response

{
  "events": [
    {
      "event_key": "call-3",
      "event_type": "CapitalCallIssued",
      "seq": 7
    },
    {
      "event_key": "call-3|lp-a",
      "event_type": "CallAllocated",
      "seq": 8
    }
  ]
}

POST /funds/{fund_id}/statements

Issue a partner statement

Issue a statement on a date with the figures the fund ledger gives: a header and one line per partner. Admins only.

Parameters

NameInTypeRequiredDescription
fund_idpathstringyesThe fund's id, as GET /funds lists it.

Request body

StatementIn

Responses

StatusBodyMeaning
201FundRecordedOutSuccessful Response
401ErrorOutMissing, malformed or invalid bearer token.
403ErrorOutYour role in this tenant does not allow this request, or the tenant is read-only.
404ErrorOutNo such company/fund, or you are not a member of it (indistinguishable on purpose).
409GuardRefusalOutRefused by a named capital rule; nothing was recorded.
413ErrorOutThe JSON body exceeds the size the API accepts.
422ErrorOutThe body is not a valid event: unknown type, unknown or missing field, bad value.

Example 201 response

{
  "events": [
    {
      "event_key": "call-3",
      "event_type": "CapitalCallIssued",
      "seq": 7
    },
    {
      "event_key": "call-3|lp-a",
      "event_type": "CallAllocated",
      "seq": 8
    }
  ]
}

Service

Liveness.

GET /health

Liveness — no token needed

Answers 200 while the application is up. Needs no token; says nothing about any tenant.

Responses

StatusBodyMeaning
200HealthOutSuccessful Response

Example 200 response

{
  "deployment": "saas",
  "edition": "saas",
  "status": "ok"
}

Models

CompanyOut

A company (or a fund) the caller is a member of, with the caller's role in it.

FieldTypeRequiredDescription
idstringyesTenant id used in every path, e.g. /companies/{company_id}/register.
namestringyesThe tenant's name.
rolestringyesadmin | viewer | auditor | employee (company) or lp (fund).

Example

{
  "id": "co-lefkara",
  "name": "Lefkara Robotics Ltd",
  "role": "admin"
}

ConversionOut

One instrument converting in a modelled round.

FieldTypeRequiredDescription
instrument_idstringyesThe instrument converting.
holder_idstringyesIts holder.
amountstringyesAmount converting, decimal string.
discount_pricestring or nullnoRound price less the discount, if any.
cap_pricestring or nullnoPrice at the valuation cap, if any.
pricestringyesThe price applied.
basisstringyesdiscount | cap | round — which price applied.
sharesintegeryesWhole shares issued on conversion.
paidstringyesshares × price, cents.
remainderstringyesamount − paid.

Example

{
  "amount": "50000",
  "basis": "discount",
  "cap_price": "800.00",
  "discount_price": "320.00",
  "holder_id": "angel-1",
  "instrument_id": "asa-1",
  "paid": "49920.00",
  "price": "320.00",
  "remainder": "80.00",
  "shares": 156
}

DilutionLineOut

One line of the before/after dilution table.

FieldTypeRequiredDescription
keystringyesholder_id or plan_id.
kindstringyesholder | pool.
beforestringyesAs-converted shares + options, exact ("num/den" when fractional).
afterstringyesThe same after the round.
pct_beforestringyesPercent, 4 decimals (display only).
pct_afterstringyesPercent, 4 decimals (display only).

Example

{
  "after": "3500",
  "before": "3500",
  "key": "andreas",
  "kind": "holder",
  "pct_after": "56.0000",
  "pct_before": "70.0000"
}

ErrorOut

The body of every error except a guard refusal: 401, 403, 404, 413, 429 and the 422s Ekvi raises itself. detail is one English sentence for a person; branch on the status code, not on the text.

FieldTypeRequiredDescription
detailstringyesWhat went wrong, in one sentence.

Example

{
  "detail": "role 'viewer' cannot record events"
}

EventRecorded

One event written to the ledger.

FieldTypeRequiredDescription
seqintegeryesPosition in the company's ledger; strictly increasing.
event_typestringyesThe event's type, e.g. Allotment.
event_keystringyesThe event's unique key within the company (event_id, or class_id / plan_id / valuation_id for definitions). Posting the same key again answers 409 unique_event_key.

Example

{
  "event_key": "A-2025-01",
  "event_type": "Allotment",
  "seq": 42
}

ExpenseLineOut

One grant in an IFRS 2 expense schedule. Amounts are null on a line that is not measured.

FieldTypeRequiredDescription
grant_idstringyesThe grant.
holder_idstringyesThe grantee.
plan_idstringyesThe option plan.
quantityintegeryesOptions granted.
statusstringyesok | missing_fair_value | no_valuation_on_grant_date.
fair_value_per_optionstring or nullnoRecorded fair value per option.
methodstring or nullnoValuation method recorded with the fair value.
total_fair_valuestring or nullnoquantity × fair value, cents.
cumulative_startstring or nullnoCumulative expense at the period start.
cumulative_endstring or nullnoCumulative expense at the period end.
expensestring or nullnoExpense recognised in the period.
reversedstring or nullnoExpense reversed in the period (forfeiture).
remainingstring or nullnoFair value not yet recognised.
forfeited_unvestedintegeryesUnvested options forfeited in the period.

Example

{
  "cumulative_end": "190.00",
  "cumulative_start": "100.00",
  "expense": "90.00",
  "fair_value_per_option": "0.90",
  "forfeited_unvested": 0,
  "grant_id": "G-1",
  "holder_id": "eleni",
  "method": "black_scholes",
  "plan_id": "esop-2025",
  "quantity": 480,
  "remaining": "242.00",
  "reversed": "0.00",
  "status": "ok",
  "total_fair_value": "432.00"
}

ExpenseReportOut

IFRS 2 expense schedule for a period. complete is false when a grant could not be measured; such grants are listed with their status and left out of total_expense — never given a guessed value.

FieldTypeRequiredDescription
company_idstringyesThe company of the path.
period_startstringyesISO.
period_endstringyesISO.
completebooleanyesFalse when any grant could not be measured.
total_expensestringyesOver the measured lines only, cents.
excluded_grantsintegeryesLines not in total_expense (status other than ok).
linesarray of ExpenseLineOutyesOne line per grant.

Example

{
  "company_id": "co-lefkara",
  "complete": true,
  "excluded_grants": 0,
  "lines": [
    {
      "cumulative_end": "190.00",
      "cumulative_start": "100.00",
      "expense": "90.00",
      "fair_value_per_option": "0.90",
      "forfeited_unvested": 0,
      "grant_id": "G-1",
      "holder_id": "eleni",
      "method": "black_scholes",
      "plan_id": "esop-2025",
      "quantity": 480,
      "remaining": "242.00",
      "reversed": "0.00",
      "status": "ok",
      "total_fair_value": "432.00"
    }
  ],
  "period_end": "2026-06-30",
  "period_start": "2026-01-01",
  "total_expense": "90.00"
}

FundIn

A new fund; the caller becomes its admin.

FieldTypeRequiredDescription
namestringyesThe fund's name; must not be blank.

Example

{
  "name": "Akamas Ventures I"
}

FundRecordedOut

One recording in a fund: the event posted first, then the lines the road wrote with it.

FieldTypeRequiredDescription
eventsarray of EventRecordedyes

Example

{
  "events": [
    {
      "event_key": "call-3",
      "event_type": "CapitalCallIssued",
      "seq": 7
    },
    {
      "event_key": "call-3|lp-a",
      "event_type": "CallAllocated",
      "seq": 8
    }
  ]
}

GuardRefusalOut

409 Conflict: the request was understood and refused by a named capital rule. Nothing was recorded.

FieldTypeRequiredDescription
detailRejectionyes

Example

{
  "detail": {
    "detail": "allotment of 2000 exceeds authorized 1000",
    "guard": "guard_allotment_within_authorized"
  }
}

HealthOut

Liveness of the installation. Needs no token.

FieldTypeRequiredDescription
statusstringyesAlways ok when the app answers.
deploymentstringyessaas | on-prem.
editionstringyessaas | on-prem.

Example

{
  "deployment": "saas",
  "edition": "saas",
  "status": "ok"
}

HolderLineOut

One register line. The s.105 particulars are null when the holder has no HolderRecorded on the date; consideration_recorded is the subscription consideration recorded on the shares held, null for a holder that never held shares. The capacity (nominee, trustee) is not here: it is outside the register extract (Cap. 113 s.112).

FieldTypeRequiredDescription
holder_idstringyesThe holder's id in this company's ledger.
outstandingintegeryesShares held on the date, all classes.
optionsintegeryesUnexercised options outstanding on the date.
pct_outstandingstringyesShare of issued shares, percent with 4 decimals (display only).
pct_fully_dilutedstringyesShare of the fully diluted count, percent with 4 decimals.
legal_namestring or nullnoName as entered in the register.
kindstring or nullnonatural_person | legal_entity | joint_holding.
addressstring or nullnoAddress as entered in the register.
date_enteredstring or nullnoDate entered in the register, ISO.
date_ceasedstring or nullnoDate ceased to be a member, ISO.
consideration_recordedstring or nullnoDecimal string, cents.

Example

{
  "address": "12 Makariou Ave, 1065 Nicosia, Cyprus",
  "consideration_recorded": "3500.00",
  "date_entered": "2025-02-01",
  "holder_id": "andreas",
  "kind": "natural_person",
  "legal_name": "Andreas Christofi",
  "options": 0,
  "outstanding": 3500,
  "pct_fully_diluted": "70.0000",
  "pct_outstanding": "77.7778"
}

InstrumentOut

ASA / convertible instrument: not shares until conversion, hence separate from lines and outside FD.

FieldTypeRequiredDescription
instrument_idstringyesThe AsaSubscribed event_id.
holder_idstringyesThe investor.
amountstringyesInvested amount, decimal string.
discountstring or nullnoConversion discount as a fraction (0.20 = 20 %).
valuation_capstring or nullnoValuation cap, decimal string.
longstop_datestring or nullnoLongstop date, ISO.
converted_bystring or nullnoevent_id of the InstrumentConverted, once converted.

Example

{
  "amount": "50000",
  "discount": "0.20",
  "holder_id": "angel-1",
  "instrument_id": "asa-1",
  "longstop_date": "2027-06-30",
  "valuation_cap": "4000000"
}

PoolLineOut

An option plan's pool on as_of.

FieldTypeRequiredDescription
plan_idstringyesThe option plan.
pool_sizeintegeryesOptions the plan may grant.
grantedintegeryesOptions granted from the pool.
exercisedintegeryesOptions exercised.
availableintegeryesWhat the pool can still grant.

Example

{
  "available": 520,
  "exercised": 0,
  "granted": 480,
  "plan_id": "esop-2025",
  "pool_size": 1000
}

RatioAdjustmentOut

Anti-dilution adjustment in NVCA notation: CP2 = CP1 × (A + B) / (A + C); exact fractions are given as "num/den" strings.

FieldTypeRequiredDescription
class_idstringyesThe protected class.
methodstringyesThe anti-dilution method of the class.
original_pricestringyesThe class's original issue price.
ratio_beforestringyesConversion ratio before the round.
conversion_price_beforestringyesCP1.
astringyesA: shares outstanding before the round (as the method counts them).
bstringyesB: shares the new money would buy at CP1.
cintegeryesC: shares actually issued in the round.
conversion_price_afterstringyesCP2.
ratio_afterstringyesConversion ratio after the round.

Example

{
  "a": "5000",
  "b": "625",
  "c": 1250,
  "class_id": "pref-a",
  "conversion_price_after": "360",
  "conversion_price_before": "400",
  "method": "broad_based_weighted_average",
  "original_price": "400",
  "ratio_after": "1.111111",
  "ratio_before": "1"
}

RegisterOut

The register of members projected from the ledger on as_of.

FieldTypeRequiredDescription
company_idstringyesThe company of the path.
as_ofstringyesThe projection date, ISO.
total_outstandingintegeryesIssued shares on the date.
total_optionsintegeryesOutstanding options on the date.
fully_dilutedintegeryesOutstanding shares plus outstanding options.
linesarray of HolderLineOutyesOne line per holder.
instruments_totalstringyesSum of unconverted instrument amounts, decimal string.
instrumentsarray of InstrumentOutyesASAs and convertibles, outside the share count.

Example

{
  "as_of": "2026-10-12",
  "company_id": "co-lefkara",
  "fully_diluted": 5000,
  "instruments": [],
  "instruments_total": "0",
  "lines": [
    {
      "address": "12 Makariou Ave, 1065 Nicosia, Cyprus",
      "consideration_recorded": "3500.00",
      "date_entered": "2025-02-01",
      "holder_id": "andreas",
      "kind": "natural_person",
      "legal_name": "Andreas Christofi",
      "options": 0,
      "outstanding": 3500,
      "pct_fully_diluted": "70.0000",
      "pct_outstanding": "77.7778"
    }
  ],
  "total_options": 500,
  "total_outstanding": 4500
}

RegisterSummaryOut

Totals of a register, before or after a modelled round.

FieldTypeRequiredDescription
total_outstandingintegeryesIssued shares.
total_optionsintegeryesOutstanding options.
fully_dilutedintegeryesShares plus options.
capitalizationstringyesAs-converted capitalization, exact.
instruments_totalstringyesUnconverted instruments, decimal string.

Example

{
  "capitalization": "5000",
  "fully_diluted": 5000,
  "instruments_total": "50000",
  "total_options": 500,
  "total_outstanding": 4500
}

Rejection

A capital rule that refused the request: the guard's stable name and its sentence.

FieldTypeRequiredDescription
guardstringyesStable machine name of the rule that refused (a guard_* function, or a named ledger rule such as unique_event_key). Safe to branch on.
detailstringyesThe rule's explanation, in English.

Example

{
  "detail": "allotment of 2000 exceeds authorized 1000",
  "guard": "guard_allotment_within_authorized"
}

RoundModelOut

What the round would do — nothing is recorded. proposed_events are the ledger events a writer would post one by one to make it real; post is the register they would produce.

FieldTypeRequiredDescription
company_idstringyesThe company of the path.
as_ofstringyesThe register date the round is modelled on, ISO.
round_idstringyesThe round's id from the terms.
pricestringyesPrice per share, cents.
price_exactstringyesPrice per share, exact fraction.
pricing_capitalizationstringyesThe capitalization the price is computed on.
capitalization_poststringyesCapitalization after the round.
pool_top_upintegeryesOptions added to the pool before the round (pool shuffle).
pool_pct_poststringyesPool share after the round, percent.
post_money_impliedstringyesPrice × post capitalization.
new_moneystringyesSum of subscriptions.
shares_issuedintegeryesNew shares, subscriptions and conversions.
subscriptionsarray of SubscriptionOutyesNew money.
conversionsarray of ConversionOutyesInstruments converting.
adjustmentsarray of RatioAdjustmentOutyesAnti-dilution adjustments.
dilutionarray of DilutionLineOutyesBefore/after table.
proposed_eventsarray of objectyesEvents in the same shape POST /companies/{company_id}/events accepts.
preRegisterSummaryOutyesTotals before.
postRegisterSummaryOutyesTotals after.

Example

{
  "adjustments": [],
  "as_of": "2026-10-12",
  "capitalization_post": "6250",
  "company_id": "co-lefkara",
  "conversions": [],
  "dilution": [
    {
      "after": "3500",
      "before": "3500",
      "key": "andreas",
      "kind": "holder",
      "pct_after": "56.0000",
      "pct_before": "70.0000"
    }
  ],
  "new_money": "500000",
  "pool_pct_post": "8.0000",
  "pool_top_up": 0,
  "post": {
    "capitalization": "6250",
    "fully_diluted": 6250,
    "instruments_total": "50000",
    "total_options": 500,
    "total_outstanding": 5750
  },
  "post_money_implied": "2500000",
  "pre": {
    "capitalization": "5000",
    "fully_diluted": 5000,
    "instruments_total": "50000",
    "total_options": 500,
    "total_outstanding": 4500
  },
  "price": "400.00",
  "price_exact": "400",
  "pricing_capitalization": "5000",
  "proposed_events": [
    {
      "class_id": "common",
      "date": "2026-10-12",
      "event_id": "seed-fund-x",
      "holder_id": "fund-x",
      "price_per_share": "400.00",
      "quantity": 1250,
      "round_id": "seed",
      "type": "Allotment"
    }
  ],
  "round_id": "seed",
  "shares_issued": 1250,
  "subscriptions": [
    {
      "amount": "500000",
      "holder_id": "fund-x",
      "paid": "500000.00",
      "remainder": "0.00",
      "shares": 1250
    }
  ]
}

StatementIn

Issue a partner statement on a date with the figures the fund ledger gives.

FieldTypeRequiredDescription
statement_idstringyesYour id for the statement; unique within the fund.
datestringyesStatement date, ISO (YYYY-MM-DD).

Example

{
  "date": "2026-06-30",
  "statement_id": "st-2026-q2"
}

SubscriptionOut

One new-money subscription in a modelled round.

FieldTypeRequiredDescription
holder_idstringyesThe subscriber.
amountstringyesAmount subscribed, decimal string.
sharesintegeryesWhole shares the amount buys.
paidstringyesshares × price, cents.
remainderstringyesamount − paid: the part that buys no whole share.

Example

{
  "amount": "500000",
  "holder_id": "fund-x",
  "paid": "500000.00",
  "remainder": "0.00",
  "shares": 1250
}

ValidationErrorOut

422 for a query or path parameter FastAPI could not read (for example as_of=yesterday). An event body Ekvi cannot read answers 422 with an ErrorOut instead.

FieldTypeRequiredDescription
detailarray of objectyesFastAPI's list of {loc, msg, type} entries.

Example

{
  "detail": [
    {
      "loc": [
        "query",
        "as_of"
      ],
      "msg": "Input should be a valid date",
      "type": "date_parsing"
    }
  ]
}

VestingLineOut

One option grant and where its vesting stands on as_of.

FieldTypeRequiredDescription
grant_idstringyesThe OptionGranted event_id.
holder_idstringyesThe grantee.
plan_idstringyesThe option plan.
quantityintegeryesOptions granted.
vestedintegeryesOptions vested on the date.
exercisedintegeryesOptions exercised on or before the date.
cancelledintegeryesOptions cancelled on or before the date.
lapsedintegeryesOptions that expired unexercised (projection from expiry_date).
exercisableintegeryesVested, not exercised, not cancelled, not lapsed.
outstandingintegeryesGranted minus exercised, cancelled and lapsed.
fmv_at_grantstring or nullnoFMV per share on the grant date, if recorded.
valuation_at_grantstring or nullnovaluation_id in force on the grant date.

Example

{
  "cancelled": 0,
  "exercisable": 120,
  "exercised": 0,
  "fmv_at_grant": "1.50",
  "grant_id": "G-1",
  "holder_id": "eleni",
  "lapsed": 0,
  "outstanding": 480,
  "plan_id": "esop-2025",
  "quantity": 480,
  "valuation_at_grant": "val-2025",
  "vested": 120
}

Event types

The body of POST /companies/{company_id}/events (Event.*) and of POST /funds/{fund_id}/events (FundEvent.*): an object with type set to the event's name and the fields below. Unknown fields are refused; the company or fund is never a field — it is the one in the path.

Event.Allotment

Issue (allotment) of shares to a holder. price_per_share is the subscription price, not the nominal value.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
class_idstringyesThe share class's id (from ShareClassDefined).
quantityintegeryesNumber of shares or options; a whole number.
price_per_sharestringyesDecimal string.
round_idstringno
certificate_nostringno

Event.AsaSubscribed

Subscription to an advance subscription agreement (the Cyprus SAFE) — an instrument, not shares. Before conversion the holder is not a member: it does not enter the Register of Members, issued or FD (Cap. 113 s.105; position 2 of the 2026-09-18 report). event_id is the instrument's identifier, and InstrumentConverted refers to it.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
amountstringyesDecimal string.
discountstringnoDecimal string.
valuation_capstringnoDecimal string.
longstop_datestring (date)no

Event.AuthorizedCapitalIncreased

Increase of a class's authorized capital by a general meeting resolution (Cap. 113 s.62). new_authorized is the class's whole new ceiling, not an increment: this way the event reads without arithmetic over history. resolution_date is when the resolution was passed; HE14 (15 days) is counted from it, while date is when the projection starts seeing the new ceiling (usually the same date).

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
class_idstringyesThe share class's id (from ShareClassDefined).
new_authorizedintegeryes
resolution_datestring (date)yes

Event.Cancellation

Cancellation of shares a holder holds in a class: the holding and the issued count go down by quantity. More than the holder holds is refused; reason says why the shares were cancelled.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
class_idstringyesThe share class's id (from ShareClassDefined).
quantityintegeryesNumber of shares or options; a whole number.
reasonstringyes

Event.ConversionRatioAdjusted

Anti-dilution: the class's new conversion_ratio after a down round (Ekvi derives it per NVCA: CP2 = CP1 × (A + B) / (A + C) for weighted average, CP2 = round price for full ratchet; ratio = OIP / CP2). new_ratio is the whole new value, not an increment. Adjustments go up only: a ratio below the current one is refused (guard_ratio_not_decreased); cause_round_id must be a recorded round (guard_round_defined).

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
class_idstringyesThe share class's id (from ShareClassDefined).
new_ratiostringyesDecimal string.
cause_round_idstringyes
methodone of: broad_based, narrow_based, full_ratchetyes

Event.FundingRoundRecorded

A round as a record: an informational event that Allotment.round_id and InstrumentConverted.round_id refer to (a reference to an unrecorded round is refused by guard_round_defined). It issues no shares and changes no holding: price and amounts are deal terms; the issue is separate Allotment events. round_id is the identifier (like class_id of a class); date is when the projection starts seeing the round (usually close_date).

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
round_idstringyes
namestringyes
kindone of: pre_seed, seed, series_a, series_b, series_c, bridge, convertible, asayesOne of the listed values.
pre_moneystringyesDecimal string.
amountstringyesDecimal string.
price_per_sharestringyesDecimal string.
statusone of: planned, open, closedyes
close_datestring (date)no
lead_investorstringno

Event.GrantFairValueRecorded

IFRS 2: fair value of one option of a grant at grant date (equity-settled: measured once and not remeasured, IFRS 2.10–11), so a second event for the same grant is refused (guard_fair_value_once). method — the model (Black-Scholes, binomial, …), source — who valued it.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
grant_idstringyesThe OptionGranted event_id.
fair_value_per_optionstringyesDecimal string.
methodstringyes
sourcestringno

Event.HolderRecorded

The particulars of a holder — the member as an entity behind the opaque holder_id.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
kindone of: natural_person, legal_entity, joint_holdingyesOne of the listed values.
legal_namestringyesName as it goes into the register (Cap. 113 s.105(1)(a)).
capacityone of: own_account, nominee, trustee, personal_representativeyesIn what capacity the holder holds: own_account unless a nominee, trustee or representative.
addressstringnoAddress as it goes into the register (Cap. 113 s.105(1)(a)).
descriptionstringno
joint_member_idsarray of stringno
registration_numberstringno
incorporation_jurisdictionstringno
is_subsidiary_of_companybooleanno
became_member_while_employedbooleanno
connected_person_s33booleanno
tax_residencystringno
cy_domiciledbooleanno
reporting_categoryone of: founder, investor, employee, advisor, otherno
principal_notestringno

Event.InstrumentConverted

Conversion of an instrument into shares: behaves like an Allotment to the instrument's holder (authorized, nominal value, basis = quantity × price_per_share) and extinguishes the instrument. One instrument converts once. round_id — the round in which the instrument became shares; as for Allotment, a reference to an unrecorded round is refused (guard_round_defined).

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
instrument_idstringyes
class_idstringyesThe share class's id (from ShareClassDefined).
quantityintegeryesNumber of shares or options; a whole number.
price_per_sharestringyesDecimal string.
certificate_nostringno
round_idstringno

Event.OpeningBalanceRecorded

A holder's position as it stood on a date, entered without the events that produced it — the first line of a register whose history before that date is not in this ledger (an import of a snapshot: "Andreas holds 3,500,000 ordinary shares today").

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
class_idstringyesThe share class's id (from ShareClassDefined).
quantityintegeryesNumber of shares or options; a whole number.
consideration_per_sharestringnoDecimal string.
certificate_nostringno
sourcestringno

Event.OptionGranted

A grant of options with vesting terms. vesting_start defaults to the grant date when not given.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
plan_idstringyesThe option plan's id (from OptionPlanAdopted).
quantityintegeryesNumber of shares or options; a whole number.
strikestringyesDecimal string.
scheduleone of: immediate, monthly, cliff_onlyyes
cliff_monthsintegeryes
vesting_monthsintegeryes
vesting_startstring (date)no
expiry_datestring (date)no

Event.OptionPlanAdopted

Option plan: the pool and the share class issued on exercise. Grants above the pool are refused.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
plan_idstringyesThe option plan's id (from OptionPlanAdopted).
namestringyes
pool_sizeintegeryes
class_idstringyesThe share class's id (from ShareClassDefined).

Event.OptionsCancelled

Cancellation (forfeiture) of a grant's unexercised options (leaver, expiry). Above the remainder is refused.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
grant_idstringyesThe OptionGranted event_id.
quantityintegeryesNumber of shares or options; a whole number.
reasonstringyes

Event.OptionsExercised

Exercise: the grant's holder receives shares of the plan's class. Above vested is refused.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
grant_idstringyesThe OptionGranted event_id.
quantityintegeryesNumber of shares or options; a whole number.
certificate_nostringno

Event.OwnershipDeclared

Who owns a legal-entity holder, as the company was told: one link of the ownership chain the register of beneficial owners is built from (rule cy.ubo.legal_entity_member_requires_look_through).

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
holder_idstringyesThe holder's id in this company's ledger (any stable id you choose).
owner_idstringyes
owner_namestringyes
owner_kindone of: natural_person, legal_entity, joint_holdingyes
fractionstringyesExact fraction: "3/5" or "0.6".
declared_onstring (date)yes
sourcestringno

Event.ShareClassDefined

A share class and its terms on exit.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
class_idstringyesThe share class's id (from ShareClassDefined).
namestringyes
kindone of: common, preferred, option, warrant, convertible, asayesOne of the listed values.
authorizedintegeryes
nominal_valuestringyesDecimal string.
seniorityintegerno
liq_multiplestringnoDecimal string.
anti_dilutionone of: none, broad_based, narrow_based, full_ratchetno
participatingbooleanno
participation_capstringnoDecimal string.
conversion_ratiostringnoDecimal string.
votes_per_shareintegerno

Event.Transfer

Transfer of shares between holders. date is the date the transfer is recorded in the Register of Members (the projection changes from it, and HE57 is counted from it too); the execution date of the instrument itself is not modelled (5B).

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
from_holder_idstringyes
to_holder_idstringyes
class_idstringyesThe share class's id (from ShareClassDefined).
quantityintegeryesNumber of shares or options; a whole number.
price_per_sharestringyesDecimal string.
instrument_refstringno

Event.ValuationRecorded

FMV per share on a date. A grant with no valuation on or before its date is recorded and carries the gap (Register.valuation_on, VestingLine.fmv_at_grant is None); it is not refused.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
valuation_idstringyes
fmv_per_sharestringyesDecimal string.
kindone of: funding_round, board_determined, 409ayesOne of the listed values.
sourcestringno

FundEvent.CapitalCallIssued

A call header. Its lines are CallAllocated events, one per partner with a non-zero line, weighted by uncalled commitment just before the call.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
call_idstringyes
purposeone of: investment, management_fee, fund_expensesyes
totalstringyesDecimal string.
due_datestring (date)yes

FundEvent.ContributionReceived

Money a partner paid against its line of a call; several partial payments are allowed.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
call_idstringyes
lp_idstringyes
amountstringyesDecimal string.

FundEvent.DistributionDeclared

A distribution header, paid on its date. Its lines are DistributionAllocated events: return of capital weighted by unreturned contributed capital, gain weighted by called capital.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
distribution_idstringyes
return_of_capitalstringyesDecimal string.
gainstringyesDecimal string.
position_idstringno

FundEvent.ExpensePaid

A fee or a fund expense paid out of the fund's cash. The fee is entered, not computed (fee bases differ from one LPA to the next); call_id names the call that funded it, when one did.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
categoryone of: management_fee, fund_expensesyes
amountstringyesDecimal string.
call_idstringno

FundEvent.FundConstituted

The fund exists from this date. Every other event must be on or after it, and there is one.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
namestringyes
legal_formone of: partnership, company, spvyes
currencystringyes
vintage_yearintegeryes
target_sizestringnoDecimal string.
registration_numberstringno

FundEvent.InvestmentMade

A tranche into a position. The first tranche opens the position; a later one with the same position_id is a follow-on into the same portfolio company. The cost is the transaction price, which is the fair value at initial recognition (IFRS 13): the position is carried at cost until a mark.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
position_idstringyes
portfolio_namestringyes
instrumentone of: shares, asa, loanyes
coststringyesDecimal string.
quantityintegernoNumber of shares or options; a whole number.
class_labelstringno
round_labelstringno

FundEvent.InvestmentMarked

The fair value of the whole remaining position on this date. A portfolio round price is an input to a mark, never the mark itself; disclosure_ref cites the company's disclosure it rests on.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
position_idstringyes
fair_valuestringyesDecimal string.
basisone of: recent_round, recent_transaction, write_down, write_off, otheryes
sourcestringyes
disclosure_refstringno

FundEvent.InvestmentRealized

An exit. cost_realized is the part of the remaining cost that leaves the position; when it is all of it, the exit is full and the position closes, with nothing left to value. remaining_fair_value is the value of what stays, and acts as a mark on the exit's date.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
event_idstringyesYour id for this event; unique within the company. Posting it again answers 409 unique_event_key.
position_idstringyes
proceedsstringyesDecimal string.
cost_realizedstringyesDecimal string.
remaining_fair_valuestringyesDecimal string.

FundEvent.LpAdmitted

A partner joins with a commitment. Only before the first call: a later closing changes every allocation weight retroactively (equalisation), which v1 does not model.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
lp_idstringyes
legal_namestringyesName as it goes into the register (Cap. 113 s.105(1)(a)).
kindone of: natural_person, legal_entityyesOne of the listed values.
partner_roleone of: lp, gpyes
commitmentstringyesDecimal string.

FundEvent.StatementWithdrawn

A statement is withdrawn, never edited; a replacement is a new statement with its own id. While a statement stands, an event dated on or before it that changes its figures is refused. A withdrawn statement stands on no date, not even before the withdrawal's; the store refuses a withdrawal dated after the day it is recorded.

FieldTypeRequiredDescription
datestring (date)yesThe event's date, ISO. Projections on a date see the events on or before it.
statement_idstringyes
reasonstringyes