---
title: "How do I add records to a dataset?"
slug: "how-do-i-add-records-to-a-custom-dataset"
updated: 2026-03-26T14:19:12Z
published: 2026-03-26T14:19:12Z
canonical: "support.lusid.com/how-do-i-add-records-to-a-custom-dataset"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://support.lusid.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How do I add records to a dataset?

You can add any number of records to a dataset in accordance with the schema in its [relational dataset definition](/v1/docs/how-do-i-create-a-relational-dataset-definition) (RDD).

## Methods

LUSID APILuminesceLUSID web app

Call the [BatchUpsertRelationalData](https://www.lusid.com/docs/api/lusid/endpoints/relational-datasets/BatchUpsertRelationalData/) API and specify the scope and code of the RDD in the URL, for example:

```json
curl -X POST 'https://<your-domain>.lusid.com/api/api/relationaldatasets/MyDatasets/Addresses/$batchUpsert'
  -H 'Content-Type: application/json-patch+json' 
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "record1": {
    "dataSeries": {
      "seriesScope": "MyScope",
      "applicableEntity": {
        "entityType": "LegalEntity",
        "entityScope": null,
        "identifierScope": "MyIdentifiers",
        "identifierType": "Banks",
        "identifierValue": "X-12345",
        "subEntityId": null
      },
      "seriesIdentifiers": {
        "AddressType": "Registered"
      }
    },
    "valueFields": {
      "Street": "1 Avenue Road",
      "City": "AcmeTown"
    },
    "metaDataFields": {
      "Email": "a@b.com"
    },
    "effectiveAt": "2025-01-01T00:00:00.0000000+00:00"
  },
  "record2": {
    "dataSeries": {
      "seriesScope": "MyScope",
      "applicableEntity": {
        "entityType": "Person",
        "entityScope": null,
        "identifierScope": "MyIdentifiers",
        "identifierType": "Managers",
        "identifierValue": "Doe-165344",
        "subEntityId": null
      },
      "seriesIdentifiers": {
        "AddressType": "Correspondence"
      }
    },
    "valueFields": {
      "Street": "3 Station Blvd",
      "City": "ToyTown"
    },
    "metaDataFields": {
      "Email": "johndoe@acme.com"
    },
    "effectiveAt": "2024-06-15T00:00:00.0000000+00:00"
  }
}'
```

***Coming soon***

Write a Luminesce SQL query using the [Lusid.RelationalDataset.<rdd-scope>.<rdd-code>.Writer](/v1/docs/lusidrelationaldatasetxxwriter) provider and execute it using a tool such as the LUSID web app, for example:

![](https://cdn.document360.io/d575ad81-c0ed-4980-bbd1-d59ac5c3de82/Images/Documentation/image-OE2DTEDL.png)

## Request fields

This section supplements the [API documentation](https://www.lusid.com/docs/api/lusid/endpoints/relational-datasets/BatchUpsertRelationalData) and on-screen help text in the LUSID web app.

You can upsert 5000 records in a single request. Each record:

- Must have a `dataSeries` comprising components that together form the primary key. See below for more information.
- Must have a `valueFields` containing key/value pairs for all the mandatory `Value` fields in the RDD, where the key is the `fieldName`. Since at least one `Value` field is always mandatory, this object cannot be empty.
- Must have a `metaDataFields` containing key/value pairs for all the mandatory `Metadata` fields in the RDD, where the key is the `fieldName`. If there are no `Metadata` fields, or all are optional, you can omit this object.
- Must have an `effectiveAt` specifying the datetime (or [cut label](/v1/docs/what-is-a-cut-label)) at which the record becomes valid in LUSID from a business perspective.

## Constructing the primary key

A record is considered unique if *all* the values in its `dataSeries` are unique. [More information](/v1/docs/anatomy-of-a-dataset).

This object consists of the following fields:

- A `seriesScope`. Note we recommend giving every record in the dataset the same `seriesScope` **providing** a dataset has no need for entitlement boundaries. However, if you want to partition a dataset and give users specific access rights using [LUSID’s IAM system](/v1/docs/identity-management-and-access-control-iam), consider differentiating the `seriesScope` of privileged records.
- An `applicableEntity` that is **one** of the allowed entity types specified in the RDD. If you want the record to apply to all entities of that type, specify just the `entityType` field. If you want to restrict the record to just one or some entities of that type, populate as many of the following fields as applicable:
  - `entityScope` to identify the [scope](/v1/docs/what-is-a-scope) of a particular `Portfolio`, `Instrument`, `InvestorRecord` or `InvestmentAccount`. For `Transaction`, `Holding` and `SettlementInstruction`, this is the scope of the parent portfolio. Omit this field for `Person` and `LegalEntity`, which are not scoped entities.
  - `identifierScope` to reference part of a [property identifier](/v1/docs/what-is-an-identifier#understanding-userdefined-property-identifiers) for a particular `Person`, `LegalEntity`, `InvestorRecord` or `InvestmentAccount`. Omit this field for `Portfolio`, `Instrument`, `Transaction`, `Holding` and `SettlementInstruction`, which do not have property identifiers.
  - `identifierType` to reference part of a property identifier for a particular `Person`, `LegalEntity`, `InvestorRecord` or `InvestmentAccount`. For `Instrument`, optionally set this field to an [instrument identifier](/v1/docs/understanding-instrument-identifiers), for example `LusidInstrumentId` or `Figi`. For `Portfolio`, `Transaction`, `Holding` and `SettlementInstruction`, specify a fixed value of `code`.
  - `identifierValue` to reference a property identifier value for a particular `Person`, `LegalEntity`, `InvestorRecord` or `InvestmentAccount`. For `Instrument`, optionally set this field to an instrument identifier value, for example `LUID_0000GDHD` or `BBG000C05BD1`. For `Portfolio`, specify the code; for `Transaction`, `Holding` or `SettlementInstruction`, specify the code of the parent portfolio.
  - `subEntityId` to optionally identify a particular `Transaction`, `Holding` or `SettlementInstruction` in a portfolio.
- A `seriesIdentifiers` containing key/value pairs for all the mandatory `SeriesIdentifier` fields in the RDD, where the key is the `fieldName`. If there are no `SeriesIdentifier` fields, or all are optional, you can omit this object.

The following table summarises `applicableEntity` fields for allowed entity types:

| `entityType` | `entityScope` | `identifierScope` | `identifierType` | `identifierValue` | `subEntityId` | Example |
| --- | --- | --- | --- | --- | --- | --- |
| `Portfolio` | <scope> |  | `code` | <code> |  | Record relates to a specific [portfolio](/v1/docs/portfolios): ```json "applicableEntity": { "entityType": "Portfolio", "entityScope": "Growth", "identifierScope": null, "identifierType": "code", "identifierValue": "UK-Equities", "subEntityId": null } ``` |
| `Instrument` | <scope> |  | <instrumentIdType> | <instrumentId> |  | Record relates to all [instruments](/v1/docs/instruments) in a specific instrument scope with ISIN identifiers: ```json "applicableEntity": { "entityType": "Instrument", "entityScope": "FixedIncome", "identifierScope": null, "identifierType": "Isin", "identifierValue": null, "subEntityId": null } ``` |
| `Transaction` | <scope> |  | `code` | <code> | <transactionId> | Record relates to a specific [transaction](/v1/docs/transactions) in a portfolio: ```json "applicableEntity": { "entityType": "Transaction", "entityScope": "Growth", "identifierScope": null, "identifierType": "code", "identifierValue": "UK-Equities", "subEntityId": "Txn001" } ``` |
| `Holding` | <scope> |  | `code` | <code> | <holdingId> | Record relates to a specific [holding](/v1/docs/holdings) in a portfolio. Note you can optionally specify a `subEntityId` of `&lt;holdingId&gt;:&lt;taxLotId&gt;` to identify a specific tax lot: ```json "applicableEntity": { "entityType": "Holding", "entityScope": "Growth", "identifierScope": null, "identifierType": "code", "identifierValue": "UK-Equities", "subEntityId": "78605785:Txn01" } ``` |
| `SettlementInstruction` | <scope> |  | `code` | <code> | <settlementInstructionId> | Record relates to a specific [settlement instruction](/v1/docs/loading-settlement-instructions) in a portfolio: ```json "applicableEntity": { "entityType": "SettlementInstruction", "entityScope": "Growth", "identifierScope": null, "identifierType": "code", "identifierValue": "UK-Equities", "subEntityId": "SI-Txn01" } ``` |
| `Person` or `LegalEntity` |  | <idTypeScope> | <idTypeCode> | <code> |  | Record relates to a specific [person](/v1/docs/representing-people-in-lusid-using-person-entities): ```json "applicableEntity": { "entityType": "Person", "entityScope": null, "identifierScope": "MyIdentifiers", "identifierType": "Managers", "identifierValue": "Doe-165344", "subEntityId": null } ``` |
| `InvestorRecord` or `InvestmentAccount` | <scope> | <idTypeScope> | <idTypeCode> | <code> |  | Record relates to a specific [investor record](/v1/docs/investor-management): ```json "applicableEntity": { "entityType": "InvestorRecord", "entityScope": "EMEA", "identifierScope": "MyIdentifiers", "identifierType": "External", "identifierValue": "123-ABCDEF", "subEntityId": null } ``` |

## Subsequent updates

You can update existing records by calling the same `BatchUpsertRelationalData` API. If all the values in the request match for the following fields in the primary key, an existing [data series](/v1/docs/anatomy-of-a-dataset) is updated:

- `seriesScope`
- All the `applicableEntity.*` fields
- All the `seriesIdentifiers` key/value pairs
- `effectiveAt`

If all match but the `effectiveAt` is different, a new time-variant [data point](/v1/docs/anatomy-of-a-dataset) is added to an existing data series. You can retrieve all the data points in a data series by calling the `QueryRelationalData` API with `queryMethod` set to `TimeSeries`.

> **Note:** If `effectiveAt` is a cut label and the only change is to a different cut label, then a new data point is added if this resolves to a different datetime. Otherwise, an existing record is updated.

If any value in the primary key (other than `effectiveAt`) does **not** match, a new data series is created.

In summary: LUSID updates an existing data series if you change a `Value`and/or `Metadata` field. If you change any other field, LUSID creates a new data point, whether this is a time-variant addition to an existing data series, or an entirely new data series.

## Deleting records

You can delete up to 5000 records in a single request. For each record you must specify the following fields:

- `seriesScope` and `applicableEntity.entityType`
- All other `applicableEntity.*` fields that have values
- All mandatory `seriesIdentifiers` key/value pairs
- `effectiveAt` if the value is not `0001-01-01 00:00:00` UTC.

LUSID APILuminesceLUSID web app

Call the [BatchDeleteRelationalData](https://www.lusid.com/docs/api/lusid/endpoints/relational-datasets/BatchDeleteRelationalData) API and specify the scope and code of the RDD in the URL, for example:

```json
curl -X POST 'https://<your-domain>.lusid.com/api/api/relationaldatasets/MyDatasets/Addresses/$batchDelete'
  -H 'Content-Type: application/json-patch+json' 
  -H 'Authorization: Bearer <your-API-access-token>'
  -d '{
  "record1": {
    "dataSeries": {
      "seriesScope": "MyScope",
      "applicableEntity": {
        "entityType": "LegalEntity",
        "identifierScope": "MyIdentifiers",
        "identifierType": "Banks",
        "identifierValue": "X-12345"
      },
      "seriesIdentifiers": {
        "AddressType": "Registered"
      }
    },
    "effectiveAt": "2025-01-01T00:00:00.0000000+00:00",
  }
}'
```

***Coming soon***

Write a Luminesce SQL query using the [Lusid.RelationalDataset.<rdd-scope>.<rdd-code>.Writer](/v1/docs/lusidrelationaldatasetxxwriter#example-2-delete-a-record) provider and specify `'Delete' as WriteAction`.
