Browse the extensions reference

Update Portfolio Block

post/extensions/roboinvestor/{graph_id}/operations/update-portfolio-block

Part of RoboInvestor.

Patch portfolio fields and apply position deltas (add / update / dispose) atomically. Partial failures roll back.

Idempotency: supply an Idempotency-Key header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict.

Authentication

Authenticate in any one of these ways — not all of them:

  • API key in the X-API-Key header.
  • Bearer token in the Authorization header.

Path parameters

NameTypeDescription
graph_idrequiredstringGraph Id

Header parameters

NameTypeDescription
Idempotency-KeyoptionalstringIdempotency-Key

Request body

Required, application/json.

FieldTypeDescription
portfolio_idrequiredstring

Target portfolio ID.

portfoliooptionalPortfolioBlockPortfolioPatch

Patch to portfolio core fields. Omit or leave fields unset to leave the portfolio core unchanged.

PortfolioBlockPortfolioPatch fields
FieldTypeDescription
nameoptionalstring

New display name. Unset = unchanged.

descriptionoptionalstring

New description. Unset = unchanged.

strategyoptionalstring

New strategy classification. Unset = unchanged.

inception_dateoptionalstring (date)

New inception date (YYYY-MM-DD). Unset = unchanged.

base_currencyoptionalstring

New ISO 4217 base currency code. Unset = unchanged. Note: changing base currency does not retroactively reprice historical positions.

entity_idoptionalstring

New owning-entity ID. Unset = unchanged.

positionsoptionalPortfolioBlockPositions

Position deltas — additions, in-place updates, and dispositions — applied atomically with the portfolio patch.

PortfolioBlockPositions fields
FieldTypeDescription
addoptionalPortfolioBlockPositionAdd[]

New positions to mint inside this portfolio. Each references an existing security_id.

PortfolioBlockPositionAdd fields
FieldTypeDescription
security_idrequiredstring

ID of the existing security this position holds. Securities are minted via create-security; the operation returns 404 if the ID is unknown.

quantityrequirednumber

Quantity held, in units defined by quantity_type (e.g. share count for shares, face value for principal).

quantity_typeoptionalstring

Unit basis for quantity. Common values: shares (equity units), units (generic), principal (debt face value).

Default: shares

cost_basisoptionalinteger

Total cost basis for this lot, in **cents** of currency. Stored as integer cents to avoid float precision drift; $1,250.00 USD is 125000.

Default: 0

currencyoptionalstring

ISO 4217 currency code for cost_basis and current_value.

Default: USD

current_valueoptionalinteger

Latest mark-to-market value in **cents** of currency, or null if unmarked. Pair with valuation_date and valuation_source when set.

valuation_dateoptionalstring (date)

Date current_value was sourced (YYYY-MM-DD).

valuation_sourceoptionalstring

Free-text source attribution for current_value (e.g. manual, broker_statement, vendor name).

acquisition_dateoptionalstring (date)

Date the position was originally acquired (YYYY-MM-DD).

notesoptionalstring

Free-text notes attached to the position.

updateoptionalPortfolioBlockPositionUpdate[]

Patches to existing positions, addressed by position id. Unset fields on each entry are left unchanged.

PortfolioBlockPositionUpdate fields
FieldTypeDescription
idrequiredstring

Target position ID. Must belong to the portfolio identified by portfolio_id on the parent operation.

quantityoptionalnumber

New quantity in units of quantity_type. Unset = unchanged.

quantity_typeoptionalstring

New unit basis (shares | units | principal). Unset = unchanged.

cost_basisoptionalinteger

New cost basis in **cents** of the position's currency. Unset = unchanged.

current_valueoptionalinteger

New mark-to-market value in **cents**. Unset = unchanged. Set alongside valuation_date / valuation_source to record a fresh valuation event.

valuation_dateoptionalstring (date)

New valuation date (YYYY-MM-DD). Unset = unchanged.

valuation_sourceoptionalstring

New valuation source attribution. Unset = unchanged.

acquisition_dateoptionalstring (date)

New acquisition date (YYYY-MM-DD). Unset = unchanged.

notesoptionalstring

New notes. Unset = unchanged.

disposeoptionalPortfolioBlockPositionDispose[]

Positions to soft-dispose, addressed by position id. Status flips to disposed and disposition_date is stamped.

PortfolioBlockPositionDispose fields
FieldTypeDescription
idrequiredstring

Target position ID to dispose. Must belong to the portfolio identified by portfolio_id on the parent operation.

disposition_reasonoptionalstring

Optional free-text reason recorded under metadata.disposition_reason on the disposed position.

Example request

curl
curl -X POST "https://api.robosystems.ai/extensions/roboinvestor/{graph_id}/operations/update-portfolio-block" \
  -H "X-API-Key: $ROBOSYSTEMS_API_KEY" \
  -H "Idempotency-Key: <Idempotency-Key>" \
  -H "Content-Type: application/json" \
  -d '{
  "portfolio": {
    "description": "Pivoted toward defensive holdings"
  },
  "portfolio_id": "port_q1_growth_2026",
  "positions": {
    "add": [],
    "dispose": [
      {
        "disposition_reason": "Liquidated; rotated capital",
        "id": "pos_oldcorp_lot_3"
      }
    ],
    "update": [
      {
        "current_value": 1980000,
        "id": "pos_aapl_lot_1",
        "valuation_date": "2026-05-06",
        "valuation_source": "broker_statement"
      },
      {
        "current_value": 2310000,
        "id": "pos_msft_lot_1",
        "valuation_date": "2026-05-06",
        "valuation_source": "broker_statement"
      }
    ]
  }
}'

Responses

200 Successful Response

FieldTypeDescription
operationrequiredstring

Kebab-case operation name

operationIdrequiredstring

op_-prefixed ULID for audit and SSE correlation

statusrequiredstring

Operation lifecycle state

One of: completed, pending, failed

resultoptionalPortfolioBlockEnvelope

Command-specific result payload

PortfolioBlockEnvelope fields
FieldTypeDescription
idrequiredstring

Portfolio ID (port_* ULID).

namerequiredstring

Display name.

descriptionoptionalstring

Free-text description.

strategyoptionalstring

Free-text strategy classification.

inception_dateoptionalstring (date)

Date the portfolio was established.

base_currencyrequiredstring

ISO 4217 currency code for portfolio aggregates.

owneroptionalEntityLite

Embedded owning entity, when set. null for unattributed portfolios.

EntityLite fields
FieldTypeDescription
idrequiredstring

Entity ID (ent_* ULID).

namerequiredstring

Display name of the entity.

source_graph_idoptionalstring

Tenant graph this entity is anchored to, when known. null for entities not yet linked to a graph.

positionsrequiredPositionBlock[]

All positions in this portfolio, including disposed ones (filter by status for active-only display).

PositionBlock fields
FieldTypeDescription
idrequiredstring

Position ID (pos_* ULID).

quantityrequirednumber

Quantity held in quantity_type units.

quantity_typerequiredstring

Unit basis (shares, units, principal).

cost_basis_dollarsrequirednumber

Cost basis in dollars (pre-converted from cents).

current_value_dollarsoptionalnumber

Latest mark-to-market value in dollars. null when the position has not been marked.

valuation_dateoptionalstring (date)

Date the current value was sourced.

valuation_sourceoptionalstring

Free-text source attribution for the valuation.

acquisition_dateoptionalstring (date)

Date the position was acquired.

statusrequiredstring

Lifecycle state (active, disposed, archived). See PositionResponse.status for the full vocabulary.

notesoptionalstring

Free-text notes attached to the position.

securityrequiredSecurityLite

Embedded security details — name, type, issuer.

total_cost_basis_dollarsrequirednumber

Sum of cost_basis_dollars across every position.

total_current_value_dollarsoptionalnumber

Sum of current_value_dollars across every position. null when any active position lacks a mark.

active_position_countrequiredinteger

Count of positions with status='active'.

created_atrequiredstring (date-time)

Row creation timestamp (UTC).

updated_atrequiredstring (date-time)

Last-modified timestamp (UTC).

atrequiredstring

ISO-8601 UTC timestamp

createdByoptionalstring

User ID that initiated the operation (null for legacy callers)

idempotentReplayoptionalboolean

True when this envelope came from the idempotency cache — the underlying command did not execute again. False on fresh executions.

Default: false

StatusMeaning
400Invalid request
401Authentication required
403Access denied
404Resource not found
409Idempotency-Key conflict — key reused with different body
422Validation error
429Rate limit exceeded
500Internal server error