API reference

API v1 → v2

What v2 adds for corporate actions, and exactly how v1 presents the same data without changing its semantics.

API v2 reports every change to a position as a corporate action. Each action carries its taxonomy type, lifecycle, distinct timestamps, evidence hashes and validation status. v1 is unchanged: same routes, same kinds, same response shapes. Both versions read the same ledger, so they never disagree about income.

New in v2

RouteReturns
GET /v2/taxonomyEvery action type: category, ledger treatment, validation status, real-instance count, census evidence
GET /v2/actions?owner=Actions applied to a wallet, newest first: type, treatment, validation, lifecycle.state, amounts and an evidence summary
GET /v2/actions/{id}?owner=One action: the full lifecycle, six distinct timestamps, every stored issuer revision with its hash, chain evidence, journal history, and lineage
GET /v2/instruments/{mint}/lineageA mint's recorded identities, the lineage links between them, and where the earliest identity's basis is now

The TypeScript client exposes them as client.v2.taxonomy(), client.v2.actions(wallet), client.v2.action(wallet, id) and client.v2.lineage(mint).

How v1 presents each type

v1 predates the taxonomy. Types it never booked appear there as unclassified adjustments. That is true as far as it goes: no income, nothing convertible. The treatment is spelled out in reasons and headline.

v2 typev2 treatmentv1 kindv1 splitFactorv1 reasons
cash_dividendincomedividendnullunchanged
withholding_adjustmentincomedividendnullunchanged
forward_split, reverse_splitquantity_basissplitthe factorunchanged
stock_dividendquantity_basisunclassified_adjustmentnull"Stock dividend booked as a quantity adjustment, not income: units ×F, with cost basis spread across them"
spin_offbasis_allocationunclassified_adjustmentnull"Spin-off booked as a basis allocation, not income: X% of the position's value was distributed and reinvested"
rights_distributionbasis_allocationunclassified_adjustmentnull"Rights distribution booked as a basis allocation, not income: X% of the position's value came from rights sold and reinvested"
identity_changeidentityunclassified_adjustmentnull"Identity change of the underlying booked as a quantity adjustment, not income: units ×F, all cost basis carried over"
anything unmatched, or a type Corpact does not booknot_bookedunclassified_adjustmentnullthe classifier's reason

The same mapping applies everywhere v1 shows a kind: /v1/income, /v1/income/{id} (including evidence.classification.result, which reads unclassified for these types), /v1/journal, and both CSV exports. /v1/portfolio counts them in unclassifiedAdjustments.

Field-level differences

Concernv1v2
What an entry iskind: dividend, split or unclassified_adjustmenttype (18 values) plus treatment (5 values)
Booked automatically?Implicitvalidation.status: validated, unvalidated or not_built, with realInstances
Where it is in its lifeNot reportedlifecycle.state. Detail adds every step, and the revision each step supersedes
TimestampseffectiveAt; the detail's chain block has scheduledAt and effectiveAtDetail timestamps: issuer effective, issuer created, configured activation, publication block time, first observed active, ingested
Evidence hashevidenceSha256: hash of the payload at ingestionevidenceSha256: stored_payload_sha256, recomputable from the database; every revision carries its own
Issuer revisionsThe matched record onlyEvery stored revision, including cancelled and superseded ones
Spin-offs and rightsUnclassified adjustmentdistributedFraction = (M_new − M_old) ÷ M_new, plus proceedsUsd when published and plausible. Never income
Stock dividends, identity changesUnclassified adjustment, no factorfactor. Identity changes also carry underlying.from and underlying.to, and the lineage link
Withholding refundsdividendtype: withholding_adjustment with refundNote
Currency retentionNot reportedretentionRate
Dataset labelOn list responsesOn list, detail and lineage responses

What changed in v1's output

v1's semantics did not change: kinds, amounts, income totals and response shapes are the same. Three pieces of text did, because the classifier now has better evidence:

  • Stock dividends, rights and identity changes carry the reasons and headlines above. Before, they read "no income policy" or "does not reconcile".
  • Withholding refunds no longer carry the "Issuer gross/withholding/net are inconsistent" warning. They carry "Withholding refund: passes back tax withheld on an earlier distribution; not a new dividend" instead.
  • The two dividends those refunds correct (on LINx and NVOx) had no matching issuer record before, and now match. They move from unclassified_adjustment to dividend, with issuer-valued USD. The refund's Corrected record had wrongly displaced them; see Withholding refund.