Create an Investment if none exists with the given Tracking ID, or update the existing one otherwise.
This is an idempotent operation: calling it twice with the same payload results in the same end state. Safe to retry on network failure, or to replay as part of a scheduled sync from your portfolio accounting system or fund administrator's data.
Matching rule
The Investment is matched by the trackingId you supply in the request body. trackingId is required — requests without a trackingId are rejected with a 400 Bad Request.
Response
The response always includes the full Investment object plus a result field:
"result": "created"— no match was found, a new Investment was created under the suppliedfundLegalEntityId."result": "updated"— an existing Investment was found and its fields were updated.
Field semantics
| Field | Create | Update |
|---|---|---|
trackingId | Required (match key). | Required (match key). |
name | Required. | Replace if present; omit = unchanged. |
fundLegalEntityId | Required. | Ignored — Investments are tied to their fund legal entity for life. |
investmentEntityId | Required. | Ignored — Investments cannot be reassigned to a different IE via this endpoint. |
status | Optional; defaults to "active". | Replace if present; omit = unchanged. |
fundFeeIds, tags | Optional; defaults to []. | Replace if present (empty array clears); omit = unchanged. |
commitmentAmount, balanceAmount, balanceUpdatedDate, createdDate, effectiveDate, note | Optional. | Replace if present; omit = unchanged. |
Validation errors return 400 Bad Request with the offending field name.
Bulk upsert mode (caveat)
When using mode: "upsert" on the bulk POST /investments/import endpoint, every per-row field is applied to the matched Investment — there is no way to express "leave this field unchanged" within a single bulk row. Use the individual upsert endpoint above for partial updates.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||