Auditing change history using the LUSID API

Prev Next

You can call the GetEntityHistory API for a particular supported entity to audit the full change history.

To do this you require an entityUniqueId. See how to obtain one.

Consider the example of a portfolio you have just created, and which is therefore at version #1. This API returns a record for each:

  • Mandatory field you provided a value for

  • Optional field you chose to provide a value for

  • Optional field that defaults to a particular value if omitted

  • Property value you chose to add.

Each of these records has a previousValue of null, the specified or default newValue, and an action of Create. All are bundled together with an asAtVersionNumber of 1 (note only the first two records shown below):

{
  "values": [
    {
      "asAtModified": "2026-04-23T10:15:11.5487210+00:00",
      "userIdModified": "00u91lo2d7X42sdse2p7",
      "requestIdModified": "2026042310-853f8edc623943e3983e85ce487a715c",
      "reasonModified": "",
      "asAtVersionNumber": 1,
      "action": "Create",
      "attributeName": "Type",
      "previousValue": {
        "labelValue": ""
      },
      "newValue": {
        "labelValue": "Transaction"
      },
      "effectiveRange": {
        "fromDate": "2020-01-01T00:00:00.0000000+00:00",
        "untilDate": "9999-12-31T23:59:59.9999999+00:00"
      },
      "isInherited": false
    },
    {
      "asAtModified": "2026-04-23T10:15:11.5487210+00:00",
      "userIdModified": "00u91lo2d7X42sdse2p7",
      "requestIdModified": "2026042310-853f8edc623943e3983e85ce487a715c",
      "reasonModified": "",
      "asAtVersionNumber": 1,
      "action": "Create",
      "attributeName": "Id.Scope",
      "previousValue": {
        "labelValue": ""
      },
      "newValue": {
        "labelValue": "Equities"
      },
      "effectiveRange": {
        "fromDate": "2020-01-01T00:00:00.0000000+00:00",
        "untilDate": "9999-12-31T23:59:59.9999999+00:00"
      },
      "isInherited": false
    },
    ...
  ]
}

Note also the following:

  • The attributeName identifies the field or property that has changed.

  • The action is either Create or Update.

  • You can use the requestIdModified to look up more information about the underlying API request from the Insights service.

  • You can use the userIdModified to look up more information about the responsible user from the Identity service.

  • The reasonModified is only likely to be populated if the record is a staged modification awaiting approval.

Note: It may be useful to subsequently call this API with a filter of asAtVersionNumber gt 1 to ignore creation records.

Next time you edit the portfolio, the API returns a record for each bundled change. So for example, if you specify a different display name and description in the same operation then version #2 consists of two records, each:

  • Showing the previousValue and newValue

  • With an action of Update and an asAtVersionNumber of 2:

{
  "values": [
    {
      "asAtModified": "2026-04-24T07:30:02.6803150+00:00",
      "userIdModified": "00u91lo2d7X42sdse2p7",
      "requestIdModified": "2026042407-b7e7038df37843e8bdfa21bef477e306",
      "reasonModified": "",
      "asAtVersionNumber": 2,
      "action": "Update",
      "attributeName": "DisplayName",
      "previousValue": {
        "labelValue": "US"
      },
      "newValue": {
        "labelValue": "France"
      },
      "effectiveRange": {
        "fromDate": "2026-04-24T07:30:02.5549760+00:00",
        "untilDate": "9999-12-31T23:59:59.9999999+00:00"
      },
      "isInherited": false
    },
    {
      "asAtModified": "2026-04-24T07:30:02.6803150+00:00",
      "userIdModified": "00u91lo2d7X42sdse2p7",
      "requestIdModified": "2026042407-b7e7038df37843e8bdfa21bef477e306",
      "reasonModified": "",
      "asAtVersionNumber": 2,
      "action": "Update",
      "attributeName": "Description",
      "previousValue": {
        "labelValue": "This is a US portfolio"
      },
      "newValue": {
        "labelValue": "This is a French portfolio"
      },
      "effectiveRange": {
        "fromDate": "2026-04-24T07:30:02.5549760+00:00",
        "untilDate": "9999-12-31T23:59:59.9999999+00:00"
      },
      "isInherited": false
    }
  ]
}

Obtaining an entityUniqueId

You can obtain the entityUniqueId for an entity by retrieving its version information.

For example, calling the GetPortfolio API for a portfolio identified by a particular scope and code reveals a version.entityUniqueId  of 668bbeef-55d8-4f0a-a3ff-803de058ab75:

{ 
  "id": {
    "scope": "Equities",
    "code": "US-Growth"
  },
  "type": "Transaction",
  "displayName": "Instructed settlement portfolio",
  "created": "2025-01-01T00:00:00.0000000+00:00",
  "version": {
    "effectiveFrom": "2026-04-21T08:02:21.9248910+00:00",
    "asAtDate": "2026-04-21T08:02:21.7861670+00:00",
    "asAtCreated": "2026-04-09T10:28:32.4468080+00:00",
    "userIdCreated": "00u91lo2d7X42sfse2p7",
    "requestIdCreated": "2026040910-b05f687e721f476fb894455780399f12",
    "reasonCreated": "",
    "asAtModified": "2026-04-20T11:35:59.0394510+00:00",
    "userIdModified": "00u91lo2d7X42sfse2p7",
    "requestIdModified": "2026042011-d26f7daf9a24444c80e8f6c6ea189d09",
    "reasonModified": "",
    "asAtVersionNumber": 6,
    "entityUniqueId": "668bbeef-55d8-4f0a-a3ff-803de058ab75"
  },
  "isDerived": false,
  "baseCurrency": "GBP",
  ...
  }
}

Note also the asAtVersionNumber of 6, which means this entity has been created (first modification) and then modified five times.