You can record the details of a new trade by booking a transaction in an appropriate transaction portfolio. Note the following:
A transaction must resolve to:
An instrument mastered in LUSID. This can be a security or a currency instrument.
A known transaction type that defines the precise economic impact; that is, the effect on your holding in that instrument, and also potentially on holdings in other instruments in the portfolio too (for example, cash holdings).
By default, LUSID operates a ‘data load first’ policy, so transactions are upserted and resolution failures must be handled manually as a post-process step. You can increase the level of validation to reject transactions that do not resolve to instruments, to transaction types, or both.
The process of booking creates an input transaction. LUSID automatically processes every input transaction into an output transaction, with extra information (where appropriate) such as realised gain/loss or a tax calculation.
LUSID assumes the transaction, settlement and portfolio currencies are the same, but if not, or your transaction is an exchange between two currencies, you can specify exchange rates explicitly, or look them up dynamically.
The total consideration of a transaction impacts LUSID’s calculation of holding cost. You can explicitly specify total consideration, gross consideration, bond interest and other numeric data points, or ask LUSID to calculate them for you.
A transaction impacts a holding in the underlying instrument unless you explicitly target a separate holding using sub-holding keys (SHKs).
LUSID has a transaction fee engine that can automatically calculate fee amounts from formulae and either capitalise or expense them.
Booking methods
You can upsert (that is, create or update) up to 10,000 transactions per call to the BatchUpsertTransactions API, specifying in the URL:
The
scopeandcodeof the parent portfolio.A
successModeofAtomicto reject all transactions in the request if one fails validation. The default mode ofPartialmeans each transaction is validated on its own merits. Find out more about this.
In the body of the API request, specify an ephemeral ID for each transaction in the batch that can be used to track warnings and failures in the response. This can be the same as the transactionID, or different. It is not stored in LUSID.
Note: This API is recommended over UpsertTransactions because it resolves transactions to instruments using individual transaction dates rather than the generic date of the upsert operation itself, reducing the likelihood of instrument resolution failures.
Consider the following example of a transaction to purchase 10 units of BP @ £20, paying and settling in GBP in a EUR-denominated portfolio:
The
unitsandtransaction.Pricefields are populated so LUSID can utilise theBuytransaction type to calculate gross consideration.The
totalConsideration.amountis set to0to trigger LUSID to calculate total consideration from a formula in theBuytransaction type.The transaction is assigned to a
GrowthSHK using a custom property to segregate resulting holdings:
curl -X POST 'https://<your-domain>.lusid.com/api/api/transactionportfolios/UK/Equity/transactions/$batchUpsert?successMode=Partial'
-H 'Content-Type: application/json-patch+json'
-H 'Authorization: Bearer <your-API-access-token>'
-d '{
"transactionRequest-1": {
"transactionId": "Txn-0000001",
"type": "Buy",
"instrumentIdentifiers": {"Instrument/default/Figi": "BBG000C6K6G9"},
"transactionDate": "2024-05-15T00:00:00.0000000+00:00",
"settlementDate": "2024-05-18T00:00:00.0000000+00:00",
"units": 10,
"transactionPrice": {"price": 20, "type": "Price"},
"totalConsideration": {"amount": 0, "currency": "GBP"},
"properties": {
"Transaction/MySHKs/Strategy": {
"key": "Transaction/MySHKs/Strategy",
"value": {
"labelValue": "Growth"
}
}
}
}
}'Note the following in the response:
LUSID confirms the globally-unique
instrumentUid(LUID) and theinstrumentScopeof the underlying instrument.LUSID sets the
transactionStatustoActive. If you subsequently edit the transaction, this becomesAmended. See how to cancel a transaction.LUSID sets the
transactionCurrencyto the same as the settlement currency, at anexchangeRateof 1.The results of LUSID’s calculations of gross consideration and total consideration are not available. Instead, examine the output transaction.
We recommend checking the
metadatasection for transactions in a batch that were upserted but failed to resolve to instruments, to transaction types, or both. Find out more about this.If you increased the level of validation, we recommend checking the
failedsection for transactions in a batch that were rejected for failing to resolve to instruments, to transaction types, or both.
{
"values": {
"transactionRequest-1": {
"transactionId": "Txn-0000001",
"type": "Buy",
"instrumentIdentifiers": {
"Instrument/default/Figi": "BBG000C6K6G9"
},
"instrumentScope": "default",
"instrumentUid": "LUID_R7E12YK8",
"transactionDate": "2024-05-15T00:00:00.0000000+00:00",
"settlementDate": "2024-05-18T00:00:00.0000000+00:00",
"units": 10,
"transactionPrice": {
"price": 20,
"type": "Price"
},
"totalConsideration": {
"amount": 0,
"currency": "GBP"
},
"exchangeRate": 1,
"transactionCurrency": "GBP",
"properties": {
"Transaction/MySHKs/Strategy": {
"key": "Transaction/MySHKs/Strategy",
"value": {
"labelValue": "Growth"
}
}
},
"source": "default",
"entryDateTime": "2026-08-29T10:49:57.5427260+00:00",
"transactionStatus": "Active",
"resolvedTransactionTypeDetails": {
"scope": "default",
"source": "default",
"type": "Buy",
"movementConditionMatches": []
},
"version": {
"effectiveFrom": "2024-05-15T00:00:00.0000000+00:00",
"asAtDate": "2026-08-29T10:49:57.5427260+00:00",
"asAtCreated": "2026-08-29T10:49:57.5427260+00:00",
"userIdCreated": "00u91lo2d7X42sdse2p7",
"requestIdCreated": "2026082910-991496a2de9c4bfc9fd2119acf115f5f",
"reasonCreated": "",
"asAtModified": "2026-08-29T10:49:57.5427260+00:00",
"userIdModified": "00u91lo2d7X42sdse2p7",
"requestIdModified": "2026082910-991496a2de9c4bfc9fd2119acf115f5f",
"reasonModified": "",
"asAtVersionNumber": 1,
"entityUniqueId": "1f00ed82-dc5f-467f-b8b2-ad5c0cc95b30_Txn-0000001"
},
"entityLinks": []
}
},
"failed": {},
"metadata": {},
"staged": {},
...
}Navigate to Dashboard > Transactions, choose a transaction portfolio, click the Create transaction button, and follow the instructions to select a transaction type and instrument.
Note the following:
LUSID automatically calculates a Gross Trade Amount that you cannot override.
If the transaction type is set to automatically calculate other amounts (such as gross consideration, total consideration, bond interest or notional value), or to look up exchange rates from transaction to settlement and to portfolio currencies dynamically, then the relevant fields are marked with a ‘calculated value’
icon. You can override some of these fields.
More about calculated amounts.

Write a Luminesce SQL query using the Lusid.Portfolio.Txn.Writer provider and execute it from a tool such as the LUSID web app

Data fields and properties
This section supplements the API documentation and on-screen help text in the LUSID web app.
Note: The mandatory API fields assume that the transaction, settlement and portfolio currencies are the same. If not, or if you are booking a FX transaction to exchange two currencies, then you must set additional fields and properties. More information.
Fields
Fields by category | Explanation |
|---|---|
| A transaction must be uniquely identified in a portfolio; you can use the LUSID sequence APIs to auto-generate unique IDs. Specify |
| A transaction must resolve to a known transaction type determining the precise economic impact, for example |
| A transaction must resolve to an instrument mastered in LUSID. Specify at least one unique instrument identifier as a three stage key (for example, |
| Note that:
|
| Depending on the underlying instrument, this might represent a number of shares, the principle in an interest rate swap, the face value of a bond, a number of ETO contracts and so on. |
| These fields are nominally optional but required if you want LUSID to automatically calculate gross consideration for you. |
| The amount represents the total payable or receivable in settlement currency. Note the following:
Specify the ISO 4217 code of the settlement currency, for example |
| These fields are optional. If omitted, LUSID assumes the settlement and transaction currencies are the same. If different, specify the ISO 4217 code of the transaction currency. You can specify an explicit exchange rate from transaction to settlement currency, or alternatively trigger LUSID to look up a market rate in the Quote Store for you. More information. |
| If the parent portfolio has nested custodian accounts you can assign the movements of a transaction to different custodians, so for example the units from a |
Properties
You can add properties to transactions at booking time by calling the BatchUpsertTransactions API and populating the properties collection. Alternatively, use the dedicated UpsertTransactionProperties API.
Properties may be:
Any number of custom properties from the
Transactiondomain to extend the data model.Any of the available system properties to record additional information that LUSID can subsequently use in business operations, for example
Transaction/default/GrossConsiderationorTransaction/default/TradeToPortfolioRate.One or more sub-holding keys (SHKs) registered with the portfolio to assign the transaction to a specific holding once processed by the transaction type. If omitted, LUSID generates one holding in the portfolio per underlying instrument per settlement currency, with all transactions in that instrument in that currency contributing to the holding.
For information about updating or deleting properties using Upsert* APIs, see this article. Note there is also a dedicated DeletePropertiesFromTransaction API.
Subsequent updates
You can update an existing transaction by calling the BatchUpsertTransactions API. Providing you specify the ID of an existing transaction then the original is updated rather than a new one created.
Note LUSID stores every update as a separate record so you can see a full change history for transactions by calling the GetTransactions API with ShowCancelledTransactions=True, and examining the transactionStatus field:
A new (never updated) transaction has a single record with a status of
Active.An updated transaction has one record per update with a status of
Amended, followed by anActiverecord with the latest information unless thetransactionDatefield has changed (see below).A transaction has a status of
Cancelledif you:Explicitly cancelled the transaction.
Updated the
transactionDatefield. This is because LUSID automatically rebooks the transaction on the new transaction date.
To see exactly which fields have changed per update and compare new with previous values, call the GetTransactionHistory API.