Corporate actions
A corporate action is an event on an asset that changes what its holders own, such as a stock split, a merger, a spin-off, a demerger, an ISIN change or a currency change. When one of those events is active, the platform books one transaction on every custody account that held the asset the banking day before, as the legacy platform's transaction generator did, and the calculation reads the event through it. Reversing or superseding an event counter-posts those transactions; nothing is deleted.
Reading requires market_data:read and shows the events your role may see. Registering and correcting events requires market_data:write and an Aleta staff role (403 otherwise). Until your move to v1 is done, the legacy platform owns your events: registering answers 409 legacy_managed, and so does any change to an event that comes from the legacy platform. Every write takes dry_run and Idempotency-Key, and a body field a write does not know answers 400.
Data model
idstringStable identifier for the event. A UUID; treat it as opaque.
legacy_idstring or nullThe event's id on the legacy platform.
nullfor an event made in v1 or by Aleta's operations. A list filter, never an id in the path.asset_idstringThe asset the event is registered on.
affected_asset_idsstring[]Every asset the event touches,
asset_idfirst: merger and spin-off targets, the new line of an ISIN or currency change.kindstringdividend,stock_split,reverse_split,share_class_split,spinoff,merger,demerger,acquisition,rights_issue,bonus_issue,tender_offer,drip,name_change,isin_change,currency_change,delist,relistorother.categorystring or nullmandatory,voluntaryormandatory_with_choice.statusstringpending(effective in the future),active,reversedorsuperseded.effective_dateISO 8601 dateThe date the event takes effect.
ex_dateISO 8601 date or null- The ex-date.
record_dateISO 8601 date or null- The record date.
pay_dateISO 8601 date or null- The pay date.
announcement_dateISO 8601 date or null- The announcement date.
settlement_dateISO 8601 date or null- The settlement date.
detailsobjectThe kind's payload in its v1 form, also on an event from the legacy platform. Asset ids in it are v1 asset ids,
nullwhen the asset is not known. Numbers are decimal strings.overrideobject or nullAleta's correction over the event as registered:
patches,reason,author_user_idandat, eachnullwhen not recorded.nullwhen there is none. Your own overrides are in the override endpoint's answer and in the effects.sourcestringWhere the event comes from:
manualfor one registered on v1, else the legacy or vendor source.ownerstringaletafor a shared event (from the legacy platform or Aleta's operations),tenantfor one made on v1.originstringlegacyorv1.superseded_by_idstring or nullThe event that replaced this one, when
superseded.created_atRFC 3339 timestamp- When the event was registered.
updated_atRFC 3339 timestamp- When the event last changed.
Register corporate actions
Registers one event, or an array of up to 100 events in one transaction. A single object answers 201 with the event, an array with the array. The whole body is validated first: an invalid row (also an unknown field) is a 400 naming it ([2] kind must be one of: ... for an array), never a partial success. An asset that does not exist or that you can't see is a 404.
One asset has at most one live split, merger, spin-off, demerger, ISIN change or currency change per date: two in the same body are a 400, and one that meets a live event already registered is a 409.
An event whose effective date has come is active; one dated in the future is pending and books nothing yet. An active split, merger, spin-off, demerger, ISIN change or currency change books its transactions in the same transaction: one per custody account that held the asset (or one of the assets the event names) the Danish banking day before the effective date, on the custody account's default cash account. They stay unsettled until the bank's own transaction replaces them. Nothing is written, and the answer is 409, when a custody account holding the asset has no default cash account, or when the period is closed on the effective date for a custody account or the cash account it books on (the entity's closed_through). The detail names each locked custody or cash account with its entity and closing date. The other kinds book nothing.
A merger, a spin-off and a demerger book from their first two sources or targets, as the legacy platform did; an active one with fewer is a 400.
Body
asset_idstringRequired. The asset the event is registered on.
kindstringRequired. One of the kinds in the data model.
categorystring or nullmandatory,voluntaryormandatory_with_choice.effective_dateISO 8601 dateRequired.
ex_dateISO 8601 date or null- The ex-date.
record_dateISO 8601 date or null- The record date.
pay_dateISO 8601 date or null- The pay date.
announcement_dateISO 8601 date or null- The announcement date.
settlement_dateISO 8601 date or null- The settlement date.
detailsobject or nullTyped for seven kinds, and required for them; unknown keys answer
400. Numbers may be JSON numbers or decimal strings.stock_split,reverse_split:ratio_numerator,ratio_denominator(both above 0).isin_change:to_asset_id.currency_change:to_asset_id,from_currency_price,to_currency_price.merger:resulting_asset_id,sources(asset_id,ratioof 0 or more).spinoff:source_numerator,spin_offs(asset_id,denominator,value_share).demerger:sources(asset_id,holding_ratio,value_ratio). Any other kind takes an open object.
curl -X POST https://api.aleta.ai/v1/corporate-actions \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"asset_id": "019e0424-187a-72c0-93c0-a79c006bcc08",
"kind": "stock_split",
"effective_date": "2026-05-04",
"details": { "ratio_numerator": 1, "ratio_denominator": 2 }
}'
{
"id": "019e0424-3a00-7f11-8e2b-5d3c9a1b0c42",
"legacy_id": null,
"asset_id": "019e0424-187a-72c0-93c0-a79c006bcc08",
"affected_asset_ids": ["019e0424-187a-72c0-93c0-a79c006bcc08"],
"kind": "stock_split",
"category": null,
"status": "active",
"effective_date": "2026-05-04",
"ex_date": null,
"record_date": null,
"pay_date": null,
"announcement_date": null,
"settlement_date": null,
"details": { "ratio_numerator": "1", "ratio_denominator": "2", "split_ratio": "2" },
"override": null,
"source": "manual",
"owner": "tenant",
"origin": "v1",
"superseded_by_id": null,
"created_at": "2026-05-04T08:12:31.402117Z",
"updated_at": "2026-05-04T08:12:31.402117Z"
}
List corporate actions
The events you may see, newest effective_date first, in the standard v1 list envelope with as_of. Any other query field answers 400.
Query parameters
asset_idstringEvents registered on or affecting the asset.
legacy_idstringThe event with this id on the legacy platform.
kindstringOne of the kinds in the data model.
statusstringpending,active,reversedorsuperseded.from_dateISO 8601 dateEarliest
effective_date, inclusive.to_dateISO 8601 dateLatest
effective_date, inclusive. Not beforefrom_date.as_ofISO 8601 dateNo event effective after it. The envelope shows it, today when left out, where every event is listed, pending ones too.
limitintegerPage size, 100 by default, at most 1000.
cursorstringThe previous page's
next_cursor.
Retrieve a corporate action
One event in the data model's form. An unknown id, or an event you can't see, is a 404.
List what an event did
One row per custody account the event touched, in custody account order, paged with cursor and limit. A row shows the transactions the event booked there (the legacy platform's row, or the platform's own and their counter-postings) and the override you set for that custody account. Only custody accounts you can see are listed. An unknown event is a 404. An unknown query parameter is a 400.
Response
custody_account_idstring- The custody account.
cash_account_idstring or null- The cash account the transactions are booked on.
statusstringapplied,adjusted(an override for the custody account),reversedorsuperseded.adjustmentobject or null- The override's patches when it has one.
notestring or null- The override's reason when it has one.
transaction_idsstring[]- The transactions, in booking order: a reversal adds the counter-postings.
kindstring or null- The legacy platform's row kind.
effective_dateISO 8601 date or null- The date the transactions are booked on.
detailsobject or null- The legacy platform's generated payload.
sourcestring- Where the row comes from: the legacy source,
generatedoroverride. originstringlegacyorv1.
{
"data": [
{
"custody_account_id": "019e0424-2a10-7b51-9c1e-4c55d7e0a311",
"cash_account_id": "019e0424-2a10-7b51-9c1e-4c55d7e0a2f0",
"status": "applied",
"adjustment": null,
"note": null,
"transaction_ids": ["019e0424-3b80-70d2-a1a4-0f6d1c2e9b01"],
"kind": null,
"effective_date": "2026-05-04",
"details": null,
"source": "generated",
"origin": "v1"
}
],
"next_cursor": null,
"limit": 100
}
Override an event
Your own layer on top of a live event; the event itself is never rewritten. patches holds the fields to change (category, effective_date, ex_date, record_date, pay_date, announcement_date, settlement_date, details; a patched details is checked like a new event's), reason is required, and custody_account_ids limits the override to some custody accounts (leave it out for the whole tenant; an empty list is a 400). A new override for the same scope replaces the one before, and the change log keeps it. The transactions in scope are counter-posted and booked again under the override; the custody account's override wins over the tenant's.
Answers 200 with the event and every override (overrides: custody_account_id, null for the whole tenant, patches, reason, author_user_id, at). A custody account you can't see is a 404; an ended event is a 409.
curl -X POST https://api.aleta.ai/v1/corporate-actions/019e0424-3a00-7f11-8e2b-5d3c9a1b0c42/override \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"patches": { "details": { "ratio_numerator": 1, "ratio_denominator": 3 } },
"reason": "vendor typo",
"custody_account_ids": ["019e0424-2a10-7b51-9c1e-4c55d7e0a311"]
}'
Reverse an event
Ends a live event: its status becomes reversed, and every transaction it booked gets a counter-posting on the same date, linked both ways. The body is reason, which is required. Answers 200 with the event and counter_postings (custody_account_id, transaction_id, linked_transaction_id, trade_date). A 409 when the event has ended already, or when the period is closed on a transaction's date.
{
"id": "019e0424-3a00-7f11-8e2b-5d3c9a1b0c42",
"legacy_id": null,
"asset_id": "019e0424-187a-72c0-93c0-a79c006bcc08",
"affected_asset_ids": ["019e0424-187a-72c0-93c0-a79c006bcc08"],
"kind": "stock_split",
"category": null,
"status": "reversed",
"effective_date": "2026-05-04",
"ex_date": null,
"record_date": null,
"pay_date": null,
"announcement_date": null,
"settlement_date": null,
"details": { "ratio_numerator": "1", "ratio_denominator": "2", "split_ratio": "2" },
"override": null,
"source": "manual",
"owner": "tenant",
"origin": "v1",
"superseded_by_id": null,
"created_at": "2026-05-04T08:12:31.402117Z",
"updated_at": "2026-05-06T09:40:02.118540Z",
"counter_postings": [
{
"custody_account_id": "019e0424-2a10-7b51-9c1e-4c55d7e0a311",
"transaction_id": "019e0424-4c11-7a03-b2c5-1e7f2d3a8c02",
"linked_transaction_id": "019e0424-3b80-70d2-a1a4-0f6d1c2e9b01",
"trade_date": "2026-05-04"
}
]
}
Supersede an event
Registers the corrected event and ends the old one (superseded, pointing at the new one) in one transaction. The body is the new event, with the register body's fields; asset_id and kind default to the old event's, effective_date and reason are required. The old event's transactions are counter-posted and the new event books its own. Answers 201 with the new event. An event that has ended already is a 409.
curl -X POST https://api.aleta.ai/v1/corporate-actions/019e0424-3a00-7f11-8e2b-5d3c9a1b0c42/supersede \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"effective_date": "2026-05-05",
"details": { "ratio_numerator": 1, "ratio_denominator": 2 },
"reason": "wrong date"
}'
Related
- Transactions: the ledger the generated transactions are booked in.
- Assets: the assets an event is registered on.