For the complete documentation index, see llms.txt. This page is also available as Markdown.

Portfolio snapshots

New integration? Start with Integrate insights into your app. This page is the field and behavior reference; Data feeds → Portfolio snapshots lists required and optional fields per instrument type. Confirm API availability in your pilot environment with Motif.

Use the portfolio snapshot API to keep a portfolio in Motif synchronized with your own platform. Send what the investor currently owns; Motif calculates valuations, allocations and portfolio analysis, and keeps supported market prices refreshed on its regular schedules.

This API creates native portfolios. It is separate from the partner portfolio context API used to supply inline context for Clarity. No Illio Wealth account or external analytical portfolio is required.

Authentication

Send your organization API key in x-api-key. Your organization must be active. Portfolio identifiers are scoped to that organization, and the same external ID in another organization refers to a different portfolio.

The URLs below are relative to your API base URL, including /api.

Create or replace a portfolio

PUT /v1/sdk/portfolios/{externalId}

The first request creates the portfolio. Subsequent requests replace its complete holdings and cash balance. Omitted holdings are removed. Sending no holdings and zero cash empties the portfolio.

{
  "revision": 1,
  "asOf": "2026-10-01T06:00:00Z",
  "currency": "AUD",
  "cash": "12648.00",
  "holdings": [
    {
      "instrument": {
        "type": "ETF",
        "symbol": "IVV",
        "exchange": "ASX",
        "name": "iShares S&P 500 ETF"
      },
      "quantity": "25",
      "costBasisPerUnit": "50.00",
      "currency": "AUD"
    }
  ]
}

The quantity and cost in this example are illustrative. Do not treat them as market prices.

Field
Meaning

revision

A positive integer that increases with each change to this portfolio.

asOf

When your system observed the supplied portfolio, including its time zone.

currency

Three-letter portfolio currency. All holdings must use this currency.

cash

Current cash balance, as a decimal string. Always supplied, including zero.

holdings

Complete current holdings, up to 500 positions.

instrument.type

ASSET with assetId, STOCK, listed ETF, unlisted FUND, or externally held CRYPTO.

instrument.symbol

Exact listing symbol or unlisted fund share-class code, such as an APIR code.

instrument.exchange

Required in uppercase for listed instruments, for example ASX. Omit for unlisted funds and crypto.

instrument.name

Human-readable instrument name.

quantity

Positive units owned, as a decimal string.

costBasisPerUnit

Optional acquisition cost per unit, not total position cost.

valuation

Optional object with unitPrice as a decimal string and its own asOf timestamp.

For an unlisted fund, provide the manager or administrator's dated unit valuation in valuation. Listed instruments use available market prices and can use your supplied valuation when market pricing is unavailable. Repeat the cost basis and valuation in subsequent snapshots if they should be retained; omission makes them unknown in the replacement snapshot.

To replace a supplied price, send a higher revision containing the complete book and the new dated valuation. Supplied valuations belong to each position; updating one portfolio does not update the same asset in other portfolios. For a shared override, select CUSTOM on the asset and use /v1/sdk/assets/{assetId}/prices; upload fact sheets through /v1/sdk/assets/{assetId}/documents. Those operations are separate from this snapshot body. See Assets, prices and documents for price precedence and the document-ingestion boundary.

Decimal inputs support up to eight decimal places. This version supports long positions in one currency, without currency conversion. It does not accept a transaction ledger or execute trades.

Non-listed and private holdings

Use FUND for an unlisted fund share class with actual units held and a dated unit NAV, including unitized PE or VC fund interests. See the private holdings walkthrough for a complete example.

For direct private-company shares or other custom instruments, create an asset with POST /v1/sdk/assets, supply its price and reference {type:"ASSET",assetId} in the snapshot. Capital calls, distributions and fund performance measures such as IRR are not reconstructed from this holdings snapshot.

Crypto holdings

Crypto instruments use a stable instrument.externalId from your platform, plus symbol, name, blockchain and networkType. Symbols retain their case and support Unicode. Supply address only when known; omit it when absent. Do not send buyable or trading instructions.

This price and quantity are illustrative. Send the observed price, including for stablecoins and gold-backed tokens; no peg is assumed. The valuation currency must match the portfolio currency. Supplied prices appear as priceSource: "manual", distinguishing them from independently fetched market quotes. Omitted valuations are explicitly missing.

An external instrument ID is unique within your organization and must retain its symbol, blockchain, network type and contract address. Use different IDs for different networks even when symbols match. Reusing an ID for a different identity returns HTTP 409.

These records support portfolio tracking without creating wallet tokens or enabling trades. Regular calculations use the latest supplied valuation and preserve its source timestamp. Symbol-only matching does not establish independent crypto market-data coverage. Market-history backfill needs a verified provider mapping or a separate dated price feed; it is not synthesized from the current valuation. Current values and allocations calculate; historical return and risk windows remain unavailable for these books under the current snapshot contract. Those analytics require a separate verified history integration.

Retries and corrections

Retry the same payload with the same revision after a timeout. An identical revision returns the same portfolio without duplicating holdings. Holding order does not matter. A changed payload needs a higher revision; reusing an accepted revision with different content returns HTTP 409.

Older revisions and source timestamps are rejected. The snapshot is applied atomically: if an instrument is invalid, none of the holdings change. Duplicate positions for one instrument must be consolidated before sending. Base currency cannot be changed through this endpoint.

Read values and calculation status

GET /v1/sdk/portfolios/{externalId}

Writes return { portfolioId, externalId, revision, asOf, calculation, calculatedRevision, calculatedAt }. Reads add status, currency, totalValue, isComplete and holdings. Each holding includes its selected priceAsOf, separately from the book observation date.

Each returned holding is { assetId, name, symbol, quantity, costBasisPerUnit, value, missingPrice, unitPrice, priceSource }. Nullable fields are symbol, costBasisPerUnit, value, unitPrice and priceSource. Nonzero cash is represented as a holding; there is no separate cash property in the read. Do not assume the request and response holding counts or order match.

The response omits the original exchange/network/external instrument ID and each supplied valuation's observation timestamp. Retain the submitted payload and verified identity map. In particular, same-symbol instruments cannot be reliably joined by symbol or array position alone.

Status
Meaning

PENDING

The latest accepted revision is awaiting calculation.

CURRENT

Calculation has completed for this revision.

isComplete: false

At least one position has no usable valuation; the total covers valued positions only.

Poll until calculatedRevision matches the revision you submitted. Individual holdings indicate missing prices. Calculation completion does not guarantee market-data coverage or completion of model-authored research. The regular workflows continue refreshing the portfolio even if you have not sent another update.

Snapshots establish current holdings, not historical transactions. Price history describes instruments; it does not reconstruct the client's realized return, distributions or deposits and withdrawals. A transaction or cash-flow contract can be added separately when those measures are needed.

Creating a portfolio does not grant end-user access, send an invitation or enable public sharing. Configure those separately through the normal portfolio administration flow.

TypeScript SDK

Use the configured motif from the main guide after the SDK capability check passes. The external ID below identifies a portfolio. The first write also provisions its internal client record; partners do not create or supply that record.

The PortfolioSnapshotInput, PortfolioSnapshotReceipt and PortfolioSnapshotView types describe these calls.

Last updated