View as Markdown

Assets

Assets are everything a client can hold — listed securities, bonds, funds, private assets, derivatives, cash positions. Transactions and holdings reference assets by id, so the asset catalogue is the vocabulary the rest of the data speaks in. Reading assets requires the market_data:read scope; creating, updating and deleting them requires market_data:write.

Aleta keeps the shared basic data of every asset (the vendors' and Aleta's own). Your tenant corrects a field in its own layer: the shared asset is never changed, and the corrected field shows the set it comes from in sources. Anyone may look an asset up; an asset's series (prices, bond figures, factors, rates) are yours to read for the assets you hold or have held, your own assets, and the indices and ETFs Aleta has turned on for you.

Data model

idstring

Stable identifier for the asset. A UUID — treat it as opaque.

legacy_idstring or null

The id v2 and v3 show for the asset (its legacy Mongo id). null for an asset made in v1 and for one legacy has no id for. Read-only; use it to find an asset during your move, not as its id. See legacy ids.

global_asset_idstring or null

The shared asset in Aleta's global data behind this one (its own id for a shared asset your tenant has no copy of); null for an asset of your own with none behind it.

asset_typestring

The asset family — e.g. bond, equity. Fixed at creation; it determines how the platform values and reports the position.

namestring

Display name shown in the product.

currency_codestring or null

ISO 4217 code of the asset's quote currency, when one applies.

country_codestring or null

The asset's country, when known. Read-only.

isinstring or null

ISIN for listed assets. null for private and unlisted assets.

cusipstring or null

CUSIP, when the asset has one. Read-only.

figistring or null

OpenFIGI id, when the asset has one. Read-only.

valorenstring or null

Valoren, when the asset has one. Read-only.

custom_identifierstring or null

Your own identifier of the asset, when it was given one.

client_idstring or null

The client that owns the asset; null when no client owns it.

inactive_fromstring or null

The date the asset was archived from (yyyy-mm-dd); null while it is active.

bondobject or null

A bond's terms; null for any other asset: bond_type (fixed, zero_coupon or index_linked), coupon_frequency (annually, semiannually, quarterly, or other for a synced bond with none of these), day_count_convention (actual_actual, thirty_360, actual_360 or other), first_coupon_date, dated_date and maturity_date. A zero-coupon bond has only maturity_date; its other terms are null.

private_equityobject or null

A private-equity fund's terms; null for any other asset: fund_type (venture_capital, private_debt, real_asset_agriculture, leveraged_buyout, fund_of_funds, infrastructure, energy, special_situations, credit, real_asset_timberland, mezzanine_capital, and for funds from the legacy platform also growth_capital, private_equity, real_estate), region (nordic, europe, north_america, south_america, africa, oecd, north_america_europe, latin_america, france_germany, spain, asia, france, global, denmark, germany), vintage_date and expected_exit_date. Commitments are transactions, not terms (see Retrieve a fund's commitments).

ownerstring

aleta for a shared asset, tenant for your own (made through this API, owned by one of your clients, or a private asset on one of your custody accounts).

originstring

legacy when the asset came from the legacy platform, v1 when it was made here.

sourcesobject

The set each correctable field (name, isin, currency_code) comes from: external for your own value (your corrections, and every field of your own asset), global for the shared data.

as_ofstring

On a single read only: the date the asset was read as of.


GET/v1/assets

List assets

Returns the assets you hold or have held on the custody accounts you see, your own assets, and the indices and ETFs Aleta has turned on for you, oldest first, in the standard v1 list envelope with as_of. Any other query parameter is a 400.

Query parameters

isinstring

Look one ISIN up in the whole catalogue, held or not: your tenant's assets first, then Aleta's shared archive. An unknown ISIN gives an empty list and creates nothing.

privateboolean

true lists your own assets only.

lens_idstring

With private=true: the private assets of one lens, held on its custody accounts. A 400 without private=true or when it is not a UUID, a 404 for a lens you can't see.

as_ofstring

Read corrected fields as of this date (yyyy-mm-dd). Defaults to today.

limitinteger

Page size. Defaults to 100, capped at 1 000.

cursorstring

Opaque cursor from the previous page's next_cursor. Omit for the first page.

legacy_idstring

Only the assets legacy shows under this id; empty answers 400. One legacy id can name two copies of the same asset, so it can match two.

Request
GET/v1/assets
curl -G https://api.aleta.ai/v1/assets \
  -H "Authorization: Bearer {access_token}" \
  -d limit=1
Response
{
  "data": [
    {
      "id": "019e28e9-9eed-7f79-8e6b-9d43159f0f49",
      "legacy_id": "5f0475d37fe83b140c415e6b",
      "global_asset_id": null,
      "asset_type": "bond",
      "name": "0,1% Danske 23",
      "currency_code": "DKK",
      "country_code": "DK",
      "isin": "DK0009922916",
      "cusip": null,
      "figi": null,
      "valoren": null,
      "custom_identifier": null,
      "client_id": null,
      "inactive_from": null,
      "bond": { "bond_type": "fixed", "coupon_frequency": "annually", "day_count_convention": "actual_actual", "first_coupon_date": null, "dated_date": null, "maturity_date": "2023-04-01" },
      "private_equity": null,
      "owner": "aleta",
      "origin": "legacy",
      "sources": { "currency_code": "global", "isin": "global", "name": "global" }
    }
  ],
  "next_cursor": "MjAyNi0wNS0xNCAyMzo1NDoxOS42OTkxODMrMDB8MDE5ZTI4ZTktOWVlZC03Zjc5LThlNmItOWQ0MzE1OWYwZjQ5",
  "limit": 1,
  "as_of": "2026-10-16"
}

POST/v1/assets

Create an asset

Creates an asset of your own — typically a private or otherwise unlisted asset that no feed will deliver. Returns 201 with the created resource. Any other field answers 400, and so does a commitment (initial_commitment): create the asset, then book the commitment with POST /v1/transactions (kind: commitment). An ISIN or custom identifier you already have an asset with, in the same currency, answers 409 already_exists with a next_action naming that asset's PATCH, or without one when a client you don't see owns that asset; an ISIN in Aleta's shared data answers 409 already_exists with a next_action naming the shared asset's PATCH (read it with GET /v1/assets?isin=... and correct it in your layer instead of making it again). Takes dry_run and Idempotency-Key.

Body parameters

asset_typestring

One of equity, mutual_fund, etf, bond, private_equity, direct_investment or custom (400 otherwise). Required, immutable after creation.

namestring

Display name. Required.

currency_codestring

ISO 4217 quote currency (400 for an unknown code). Required for equity, mutual_fund and bond.

country_codestring

ISO 3166 two-letter country, upper case. Required for equity, mutual_fund and bond.

isinstring

ISIN, when the asset has one; it must be a valid ISIN (400 otherwise). Optional.

custom_identifierstring

Your own identifier: letters, digits and -, at most 32. Optional.

client_idstring

The client that owns the asset; you must be able to write the client (403 otherwise, 404 for a client you can't see). Optional.

bondobject

asset_type: bond only (400 otherwise). bond_type is fixed, zero_coupon or index_linked. A fixed or index_linked bond requires coupon_frequency (annually, semiannually, quarterly) and day_count_convention (actual_actual, thirty_360, actual_360) and takes first_coupon_date, dated_date and maturity_date; a zero_coupon bond takes only maturity_date. Dates are yyyy-mm-dd. Optional.

private_equityobject

Required for asset_type: private_equity, refused for any other type: fund_type (one of the first eleven in the data model), region, vintage_date and expected_exit_date, all required.

Request
POST/v1/assets
curl -X POST https://api.aleta.ai/v1/assets \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "asset_type": "custom",
    "name": "Holding ApS",
    "currency_code": "DKK",
    "country_code": "DK"
  }'
Response
{
  "id": "019e0424-187a-72c0-93c0-a79c006bcc08",
  "legacy_id": null,
  "global_asset_id": null,
  "asset_type": "custom",
  "name": "Holding ApS",
  "currency_code": "DKK",
  "country_code": "DK",
  "isin": null,
  "cusip": null,
  "figi": null,
  "valoren": null,
  "custom_identifier": null,
  "client_id": null,
  "inactive_from": null,
  "bond": null,
  "private_equity": null,
  "owner": "tenant",
  "origin": "v1",
  "sources": { "currency_code": "external", "isin": "external", "name": "external" }
}

GET/v1/assets/{id}

Retrieve an asset

Fetch a single asset by id: your tenant's asset, or Aleta's shared asset when your tenant has no copy of it. No holding is needed to look an asset up. A 404 problem when the id doesn't exist, or the asset belongs to a client you don't see.

Query parameters

as_ofstring

Read corrected fields as of this date (yyyy-mm-dd). Defaults to today.

Request
GET/v1/assets/{id}
curl https://api.aleta.ai/v1/assets/019e28e9-9eed-7f79-8e6b-9d43159f0f49 \
  -H "Authorization: Bearer {access_token}"
Response
{
  "id": "019e28e9-9eed-7f79-8e6b-9d43159f0f49",
  "legacy_id": "5f0475d37fe83b140c415e6b",
  "global_asset_id": null,
  "asset_type": "bond",
  "name": "Danske Bank 0,1% 2023",
  "currency_code": "DKK",
  "country_code": "DK",
  "isin": "DK0009922916",
  "cusip": null,
  "figi": null,
  "valoren": null,
  "custom_identifier": null,
  "client_id": null,
  "inactive_from": null,
  "bond": { "bond_type": "fixed", "coupon_frequency": "annually", "day_count_convention": "actual_actual", "first_coupon_date": null, "dated_date": null, "maturity_date": "2023-04-01" },
  "private_equity": null,
  "owner": "aleta",
  "origin": "legacy",
  "sources": { "currency_code": "global", "isin": "global", "name": "external" },
  "as_of": "2026-10-16"
}

PATCH/v1/assets/{id}

Update an asset

Corrects basic data field by field in your tenant's own layer: the field turns from Aleta's value to yours (set external), and the shared asset and its feed are never changed, so a later feed update keeps your value. Without effective_from the value corrects the whole history; with it, the value holds from that date. Returns 200 with the asset as of that date (without an as_of field). asset_type is immutable.

Refusals, in this order: 400 for the body (any other field, a null or empty name, an inactive_from other than null, or no field to change: reason and effective_from alone change nothing), 404 when your tenant has no such asset or it belongs to a client you don't see, 403 when you may not write the asset's client, 403 aleta_owned for restoring a shared asset, 409 legacy_managed for an asset from the legacy platform until the customer has moved to v1, 409 in_use for the currency of an asset that is in figures (the calculation reads the shared currency), and 409 already_exists when another asset has the ISIN in that currency, with a next_action naming its PATCH (none when a client you don't see owns it). Takes dry_run and Idempotency-Key; every change is in the asset's history.

Body parameters

namestring

Your display name. Not empty and not null.

currency_codestring or null

Your quote currency, or null to clear it.

isinstring or null

Your ISIN, or null to clear it.

effective_fromstring

The date the value holds from (yyyy-mm-dd). Optional.

inactive_fromnull

null restores an archived asset of your own. Archive with POST /v1/assets/{id}/archive.

reasonstring

Why, kept in the history. Optional.

Request
PATCH/v1/assets/{id}
curl -X PATCH https://api.aleta.ai/v1/assets/019e28e9-9eed-7f79-8e6b-9d43159f0f49 \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Danske Bank 0,1% 2023", "reason": "statement name" }'

DELETE/v1/assets/{id}

Delete an asset

Removes an asset nothing has used. Returns 204 on success, or a 404 problem if the id doesn't exist for this tenant or the asset belongs to a client you don't see. An asset that has been in figures (transactions, prices, net asset values, holdings, lots and the like) is never deleted: the delete answers a 409 in_use problem whose next_action points to POST /v1/assets/{id}/archive, and its transactions and net asset values stay. A 403 problem when you may not write the asset's client, then 403 aleta_owned for an asset of Aleta's shared data (a listed share or a vendor bond), then 409 legacy_managed for an asset from the legacy platform until the customer has moved to v1, all checked before the use. Its tag assignments are deleted with it and kept in the history. Takes dry_run and Idempotency-Key.

Request
DELETE/v1/assets/{id}
curl -X DELETE https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08 \
  -H "Authorization: Bearer {access_token}"

POST/v1/assets/{id}/archive

Archive an asset

Marks an asset inactive from a date (inactive_from), with an optional reason (at most 2,000 characters, kept in the change log); any other field answers 400. Archiving changes no figures. Send it again to move the date. You may archive an asset of a client you may write, and a firm-wide writer may archive the tenant's own assets no client owns. Returns 200 with the asset as GET /v1/assets/{id} reads it, plus archived_at, archived_by (the user; null when Aleta archived it, which never says who) and archive_reason. A 404 problem when the asset doesn't exist or belongs to a client you don't see, a 403 problem when you may not write its client, 403 aleta_owned for an asset of Aleta's shared data (owner: aleta, a listed share or a vendor bond), which only Aleta archives on the shared row, and 409 legacy_managed for any other asset from the legacy platform until the customer has moved to v1. Takes dry_run and Idempotency-Key.

Request
POST/v1/assets/{id}/archive
curl -X POST https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08/archive \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"inactive_from": "2026-03-31", "reason": "Sold out"}'

GET/v1/assets/{id}/history

List an asset's history

What changed on the asset's basic data through this API, newest first, in the standard v1 list envelope. Each entry has id, occurred_at, action (create, update, delete, archive or unarchive), kind (correction: the history was wrong; change: from effective_from; or null), effective_from (the date of a change, else null), reason, changes (field, before, after and the source set of the new value) and actor, as audit events show it: {kind, user_id, credential_id, owner_user_id, role} with kind person (user_id), machine (an API key: credential_id and the user it acts as in owner_user_id), aleta (the staff role only, never who: Aleta's ids are also taken out of before and after) or system. Changes made on the legacy platform are not carried over. A 404 problem for an asset you can't read. Takes limit and cursor; any other query parameter is a 400.

Response
{
  "data": [
    {
      "id": "019e3a61-0c5e-7d43-9b1b-5f1f6e2d1a90",
      "occurred_at": "2026-10-16T09:12:44.218311Z",
      "action": "update",
      "kind": "correction",
      "effective_from": null,
      "reason": "statement name",
      "changes": [
        { "field": "name", "before": "0,1% Danske 23", "after": "Danske Bank 0,1% 2023", "source": "external" }
      ],
      "actor": { "kind": "person", "user_id": "019d8f4e-2b1c-7a55-8d3e-6c0b9a7f4e21", "credential_id": null, "owner_user_id": null, "role": null }
    }
  ],
  "next_cursor": null,
  "limit": 100
}

Series

An asset's series are dated points: pool factors, index factors, drawing percentages, circulation amounts, drawing prices, interest rates, prices and bond analytics. Every source is listed; which one a figure uses is the hierarchy's choice, not the list's. A point shows its set (global for the shared vendor data with the vendor as provider, manual for Aleta's, a bank's code for a bank's own figures, external for your own), its owner (aleta or tenant) and its origin (legacy or v1).

The data licence. For an asset you hold or have held on the accounts you see, your own asset, or an index or ETF Aleta has turned on for you, a series lists every point. For any other asset it lists your own points only, and answers a 403 not_licensed problem when you have none (prices excepted, see below). A client's own points show only to callers that see the client.

Your own points. You write your own points only (set external; leaving set out means the same). Another set (global, manual, official_nav, a bank's) or a provider answers a 403 problem that names the way to your own; a set no point has answers 400. Changing a shared point (a vendor's, Aleta's or a bank's) answers 403 aleta_owned with a next_action naming the series' POST for your own point, also when it comes from the legacy platform; any other point from the legacy platform answers 409 legacy_managed until the customer has moved to v1. No monthly lock applies. Writes take dry_run and Idempotency-Key, and every change is logged with an optional reason.

idstring

Stable identifier for the point. Opaque; it names the asset, date and stored source.

asset_idstring

The asset.

datestring

ISO date (yyyy-mm-dd) the point applies from.

valuedecimal string

The value, without trailing zeros.

setstring

global, manual, a bank's code or external.

providerstring or null

The vendor of a global point.

ownerstring

tenant for a point you can change (yours, or any point on an asset you own), else aleta.

originstring

legacy or v1.

SeriesPathValue
Pool factorspool-factorsThe share of the principal left, 0 to 1. Bonds only.
Index factorsindex-factorsGreater than 0; the legacy platform's par factors. Bonds only.
Drawing percentagesdrawing-percentages0 to 100.
Circulation amountscirculation-amountsNot negative. Bonds with an original issued amount only; a pool bond's amount may not exceed it.
Drawing pricesdrawing-pricesGreater than 0, in the asset's currency.
Interest ratesinterest-ratesThe rate in percent, any decimal.

A value is rounded to 10 decimals (drawing prices: 8) and may have at most 18 digits before the point (drawing prices: 12; 400 otherwise).

Each series has the same four routes. Reads need market_data:read, writes market_data:write.

SeriesListCreate a pointUpdate a pointDelete a point
Pool factorsGET /v1/assets/{id}/pool-factorsPOST /v1/assets/{id}/pool-factorsPATCH /v1/pool-factors/{id}DELETE /v1/pool-factors/{id}
Index factorsGET /v1/assets/{id}/index-factorsPOST /v1/assets/{id}/index-factorsPATCH /v1/index-factors/{id}DELETE /v1/index-factors/{id}
Drawing percentagesGET /v1/assets/{id}/drawing-percentagesPOST /v1/assets/{id}/drawing-percentagesPATCH /v1/drawing-percentages/{id}DELETE /v1/drawing-percentages/{id}
Circulation amountsGET /v1/assets/{id}/circulation-amountsPOST /v1/assets/{id}/circulation-amountsPATCH /v1/circulation-amounts/{id}DELETE /v1/circulation-amounts/{id}
Drawing pricesGET /v1/assets/{id}/drawing-pricesPOST /v1/assets/{id}/drawing-pricesPATCH /v1/drawing-prices/{id}DELETE /v1/drawing-prices/{id}
Interest ratesGET /v1/assets/{id}/interest-ratesPOST /v1/assets/{id}/interest-ratesPATCH /v1/interest-rates/{id}DELETE /v1/interest-rates/{id}

The list returns the asset's points of the series, the create stores your point for a date, the update changes your point's value and the delete takes your point out; each works as described below.

/v1/assets/{id}/par-factors and /v1/par-factors/{id} are gone without an alias and answer 404: the legacy platform's par factors are index factors, and a pool factor is a series of its own.


GET/v1/assets/{id}/{series}

List a series

Returns the series, oldest first, in the standard v1 list envelope. A 404 problem when the asset doesn't exist for this tenant, a 403 not_licensed problem under the licence rule above, and a 400 for an unknown query parameter.

Pool factors also list the value the legacy platform derives for a pool bond with an original issued amount: each circulation amount divided by the issued amount, with derived: true, id: null and the circulation_amount_id it comes from. Every pool factor carries derived and circulation_amount_id after origin (false and null for a stored point), and a stored point of a date lists first.

Query parameters

from_datestring

Inclusive lower date bound (yyyy-mm-dd). Optional.

to_datestring

Inclusive upper date bound (yyyy-mm-dd). Optional.

as_ofstring

No point after this date (yyyy-mm-dd); today when left out. The page shows it.

limitinteger

Page size. Optional.

cursorstring

next_cursor of the previous page. Optional.

Request
GET/v1/assets/{id}/interest-rates
curl -G https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08/interest-rates \
  -H "Authorization: Bearer {access_token}"
Response
{
  "data": [
    {
      "id": "YnRzfGludGVyZXN0fDAxOWUwNDI0LTE4N2EtNzJjMC05M2MwLWE3OWMwMDZiY2MwOHwyMDI2LTA2LTEwfGV4dGVybmFs",
      "asset_id": "019e0424-187a-72c0-93c0-a79c006bcc08",
      "date": "2026-06-10",
      "value": "4.5",
      "set": "external",
      "provider": null,
      "owner": "tenant",
      "origin": "v1"
    }
  ],
  "next_cursor": null,
  "limit": 100,
  "as_of": "2026-10-18"
}

POST/v1/assets/{id}/{series}

Create a point

Stores your point for a date. Returns 201 for a new point, 200 when it replaced your point of that date or was the same; a point on the date of a retracted one brings it back. Index factors and interest rates are not replaced: a second point on the date answers 409 already_exists with a next_action naming the PATCH of the point that is there. A drawing price needs the asset's currency (409 no_currency without one, with a next_action naming PATCH /v1/assets/{id}, which sets it). Any other field (such as a source) answers 400.

Body parameters

datestring

ISO date (yyyy-mm-dd). Required.

valuedecimal string

Required; the series' rule above applies.

setstring

external or left out.

reasonstring

Why, kept in the change log. Optional.

Request
POST/v1/assets/{id}/pool-factors
curl -X POST https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08/pool-factors \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "date": "2026-06-30", "value": "0.875" }'

PATCH/v1/{series}/{id}

Update a point

Changes the value of your point; the same value answers 200 without a change. The date is part of the id: to move a point, delete it and create it on the new date. A 404 problem when the point doesn't exist or isn't one you can see. Body: value (required) and reason; any other field (such as a date) answers 400.

Request
PATCH/v1/interest-rates/{id}
curl -X PATCH https://api.aleta.ai/v1/interest-rates/YnRzfGludGVyZXN0fDAxOWUwNDI0LTE4N2EtNzJjMC05M2MwLWE3OWMwMDZiY2MwOHwyMDI2LTA2LTEwfGV4dGVybmFs \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "value": "4.75" }'

DELETE/v1/{series}/{id}

Delete a point

Takes your point out: it leaves every list and the calculation. A bond point is retracted and kept with who retracted it; a drawing price is deleted. Returns 204. Takes reason as a query parameter.

Request
DELETE/v1/interest-rates/{id}
curl -X DELETE https://api.aleta.ai/v1/interest-rates/YnRzfGludGVyZXN0fDAxOWUwNDI0LTE4N2EtNzJjMC05M2MwLWE3OWMwMDZiY2MwOHwyMDI2LTA2LTEwfGV4dGVybmFs \
  -H "Authorization: Bearer {access_token}"

GET/v1/assets/{id}/bond-analytics

Bond analytics

A bond's analytics per date and source: id, asset_id, date, set, provider, owner and origin, then yield_to_maturity, macaulay_duration, modified_duration, oas_risk, oa_convexity and oa_duration, decimal strings (rates as fractions, durations in years), each null when the source has none. The list and the licence work as for the series.

  • POST /v1/assets/{id}/bond-analytics stores your figures of one date (at least one figure; set external; any other field answers 400). 201, or 409 already_exists when the date has yours, with a next_action naming the PATCH to use.
  • PATCH /v1/bond-analytics/{id} changes figures of your row: a figure left out stays, null clears it, and at least one must be left. asset_id, date and source are the row's key and answer 400.
  • DELETE /v1/bond-analytics/{id} deletes your row, 204.

A shared row answers 403 aleta_owned (also when it comes from the legacy platform); any other row from the legacy platform answers 409 legacy_managed until the customer has moved to v1. A client's own rows show only to callers that see the client. Writes take dry_run, Idempotency-Key and reason.

Request
POST/v1/assets/{id}/bond-analytics
curl -X POST https://api.aleta.ai/v1/assets/019e28e9-9eed-7f79-8e6b-9d43159f0f49/bond-analytics \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "date": "2026-06-30", "yield_to_maturity": "0.0312", "modified_duration": "4.25" }'

GET/v1/assets/{id}/prices

Prices

The asset's prices (drawing prices are their own series) with id, date, value, price_kind (close, nav, ...), currency_code, set, provider, owner and origin, in the standard v1 list envelope. Every set is listed: yours (external), the vendors' (global with the vendor as provider), Aleta's (manual, official_nav) and each bank's own prices (the bank's code). A client's own prices show only to callers that see the client. Takes from_date, to_date, as_of (today when left out), set, limit and cursor; any other query parameter is a 400. Without the licence it lists your own prices only, and an empty list (200, never a 403) when you have none. owner is tenant for a price you can change; a bank's price, a global price, a parked alternate and a net asset value's prices are never tenant.

  • POST /v1/assets/{id}/prices stores your close price (set external) for a date in the asset's currency: 201; 409 already_exists when you have a price on the date, with a next_action naming its PATCH (a 409 conflict without one when the price on the date belongs to a client you don't see); 409 no_currency when the asset has no currency, with a next_action naming PATCH /v1/assets/{id}, which sets it. The value has at most 12 digits before the point and 8 after (400 otherwise). Any other field answers 400.
  • PATCH /v1/prices/{id} changes the value of your price, 200 with the price. A net asset value's prices, an official NAV (official_nav) and drawing prices are other resources (404), and a bank's price, a price read from Aleta's shared archive or a parked alternate is no price these routes change (404); any other shared price (owner: aleta, such as a vendor's global price or Aleta's manual one) answers 403 aleta_owned with a next_action naming POST /v1/assets/{asset_id}/prices (also when it comes from the legacy platform); any other price from the legacy platform answers 409 legacy_managed until the customer has moved to v1. Takes reason.
  • DELETE /v1/prices/{id} deletes your price, 204, under the same rules.
Request
POST/v1/assets/{id}/prices
curl -X POST https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08/prices \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "date": "2026-06-30", "value": "101.25" }'

GET/v1/assets/{id}/net-asset-values

Net asset values

A private-equity fund's net asset values, oldest first by effective_date, in the standard v1 list envelope: id, official_date, effective_date (the date the NAV counts from), value (the official NAV, decimal string) and estimated_value (the NAV rolled forward to effective_date: the official value plus the NAV-affecting private-equity transactions after official_date, as the legacy platform estimates it). Takes from_date and to_date (on effective_date), as_of (today when left out; no NAV after it), limit and cursor. The licence works as for the series: without it only your own NAVs, and 403 not_licensed when you have none.

  • POST /v1/assets/{id}/net-asset-values stores your NAV: official_date, value and effective_date (the official date when left out, never before it; 400). Private-equity assets with a currency only (400); you must be able to write the asset's client (403). The value has at most 18 digits before the point and 10 after (400 otherwise). 201 with the NAV, 409 already_exists when you have one on the effective date, with a next_action naming its PATCH /v1/net-asset-values/{id}. Any other field answers 400.
  • PATCH /v1/net-asset-values/{id} changes the official value of your NAV, 200; the estimate moves with it. Takes an optional reason, kept in the change log.
  • DELETE /v1/net-asset-values/{id} retracts your NAV, 204.

Writes take dry_run and Idempotency-Key, and every change is logged.

Request
POST/v1/assets/{id}/net-asset-values
curl -X POST https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08/net-asset-values \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "official_date": "2026-06-30", "effective_date": "2026-09-30", "value": "1250000" }'

GET/v1/assets/{id}/commitments

Retrieve a fund's commitments

The commitment status of one private equity fund on a date: what you have committed, what has been called (paid in), what is still uncalled and what the fund has distributed. The figures are the fund's holdings on the custody accounts you can see, each on its latest date on or before as_of and at your ownership share of it (an owner of 40 % sees 40 %), added up in the fund's currency. Before your move to v1 they are the legacy platform's figures; after it, the platform calculates them from your commitment, call and distribution transactions. Requires positions:read.

Returns 400 when id is not a uuid or as_of is not a date, 404 when the asset doesn't exist for you or is not a private equity fund, and zeros when you hold none of it.

Query parameters

as_ofstring

ISO date (yyyy-mm-dd) to read the status at. Defaults to today.

Response

asset_idstring
The fund.
as_ofstring
The date the status is read at.
fund_currency_codestring | null
The fund's currency; every amount is in it.
commitment_totaldecimal string
The commitment.
commitment_calleddecimal string
Called so far (paid in).
commitment_uncalleddecimal string
Still uncalled.
distributionsdecimal string
Distributed so far.
Request
GET/v1/assets/{id}/commitments
curl "https://api.aleta.ai/v1/assets/019e0424-187a-72c0-93c0-a79c006bcc08/commitments?as_of=2026-09-30" \
  -H "Authorization: Bearer {access_token}"
Response
{
  "asset_id": "019e0424-187a-72c0-93c0-a79c006bcc08",
  "as_of": "2026-09-30",
  "fund_currency_code": "EUR",
  "commitment_total": "1000000",
  "commitment_called": "400000",
  "commitment_uncalled": "600000",
  "distributions": "125000"
}

  • Exchange rates — the DKK rates the platform converts with.
  • Transactions — the events that reference assets.
  • Holdings — positions broken down per asset via expand=assets.
  • Tags — classify assets into taxonomies.