--- title: "How do I read and write quote metadata fields using Luminesce?" slug: "how-do-i-read-and-write-quote-metadata-fields-using-luminesce" updated: 2026-10-27T15:55:12Z published: 2026-10-27T15:55:12Z canonical: "support.lusid.com/how-do-i-read-and-write-quote-metadata-fields-using-luminesce" --- > ## 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 read and write quote metadata fields using Luminesce? You can give every quote in your domain extra information, such as the vendor that supplied it, the asset class it belongs to, or an internal quality score. Once these quote metadata fields are defined in LUSID, you can add them to the `Lusid.Instrument.Quote` and `Lusid.Instrument.Quote.Writer` providers as ordinary columns. You can then select them, filter on them and write to them like any other column on the provider. > **Note:** Quote metadata fields and the LUSID APIs that define them are currently **Early Access**. ## Understanding quote metadata fields A quote's standard fields, such as its scope, instrument, quote type, field, effective date, value and unit, say *what* the price is. Metadata fields record extra information *about* the quote. You define metadata fields once for your domain, in LUSID's quote market data field configuration. This is a schema shared by every quote in your domain. Each quote can then hold a value for any field in the schema. Each field definition has: | **Attribute** | **Description** | | --- | --- | | `fieldName` | The field's unique identifier. It may contain characters such as `.` and `/`, for example `Vendor.Score/Rank`, but no whitespace. | | `displayName` | A human-readable name for the field. | | `description` | An optional description. Luminesce uses it as the column description by default. | | `dataTypeId` | The LUSID data type of the field's values, for example `system/string`. | > **Note:** LUSID currently only supports metadata fields whose data type has a string value type, such as `system/string` or `system/iso4217Currency`. These appear in Luminesce as `Text` columns. ## Prerequisites Luminesce doesn't create metadata fields. Before you can add them to the quote providers, you must define them in LUSID by calling the `UpdateMarketDataFieldConfiguration` API with the `Quote` market data category. For example, to add three fields: ```json curl -X POST "https://.lusid.com/api/api/marketdata/fieldconfiguration/Quote/$update"  -H "Authorization: Bearer "  -H "Content-Type: application/json-patch+json"  -d '{  "add": {    "metadataFields": [      { "fieldName": "vendor", "displayName": "Vendor", "description": "The vendor that supplied the quote",        "dataTypeId": { "scope": "system", "code": "string" } },      { "fieldName": "assetClass", "displayName": "Asset Class", "description": "The asset class of the quoted instrument",        "dataTypeId": { "scope": "system", "code": "string" } },      { "fieldName": "Vendor.Score/Rank", "displayName": "Vendor score rank", "description": "The vendor's score rank for the quote",        "dataTypeId": { "scope": "system", "code": "string" } }    ]  } }' ``` The request can also have `update` (field definitions to replace) and `remove` (field names to delete) sections. To see the current fields, call `GET /api/api/marketdata/fieldconfiguration/Quote`. The rest of this article uses these three fields. ## Methods You add metadata fields to the providers using `Sys.Admin.Lusid.Provider.Configure`, the same provider you use to [configure other LUSID entity providers to read and write properties](/v1/docs/how-do-i-configure-luminesce-entity-providers-to-readwrite-properties). Configuring `Lusid.Instrument.Quote` configures `Lusid.Instrument.Quote.Writer` at the same time, and the change affects your entire domain. For each field you configure, `Sys.Admin.Lusid.Provider.Configure` reads the field's definition and fills in anything you don't supply. See [Appendix A](/docs/how-do-i-read-and-write-quote-metadata-fields-using-luminesce#appendix-a-configuration-columns) for the columns you can supply. ### Method 1: Add every metadata field If you don't pass a `Configuration` table, the providers get a column for every metadata field currently in the schema: ```sql select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote'; ``` With the fields defined above, the providers get three new columns: `Vendor`, `AssetClass` and `VendorScoreRank`. ### Method 2: Add a subset of fields To add only some fields, list their names as keys: ```sql @fields = values ('vendor'), ('Vendor.Score/Rank'); @config = select column1 as [Key] from @fields; select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote' and Configuration = @config and WriteAction = 'Set'; ``` ### Method 3: Choose column names, main columns and descriptions ```sql @fields = values ('vendor', 'QuoteVendor', true, 'The vendor that supplied the quote'), ('assetClass', null, false, null),            -- column name defaults to AssetClass ('Vendor.Score/Rank', 'ScoreRank', false, null); @config = select column1 as [Key], column2 as Name, column3 as IsMain, column4 as Description from @fields; select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote' and Configuration = @config and WriteAction = 'Set'; ``` ### Method 4: Create a separately named provider To build a separate provider pair with its own set of columns, pass `ProviderNameExtension`. This leaves the default `Lusid.Instrument.Quote` provider unchanged. The following example creates `Lusid.Instrument.Quote.Vendor` and `Lusid.Instrument.Quote.Vendor.Writer`: ```sql @config = select 'vendor' as [Key]; select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote' and ProviderNameExtension = 'Vendor' and Configuration = @config and WriteAction = 'Set'; ``` ### Updating and removing fields To pick up fields added to the schema since you last configured the providers, while keeping your existing column names, use `Modify` with no `Configuration` table: ```sql select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote' and WriteAction = 'Modify'; ``` To remove a field: ```sql @config = select 'assetClass' as [Key]; select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote' and Configuration = @config and WriteAction = 'Remove'; ``` To remove every metadata field column and return the providers to their standard columns: ```sql select * from Sys.Admin.Lusid.Provider.Configure where Provider = 'Lusid.Instrument.Quote' and WriteAction = 'Reset'; ``` See [Appendix B](/docs/how-do-i-read-and-write-quote-metadata-fields-using-luminesce#appendix-b-write-actions) for exactly what each write action does. ### Checking the result The `Error` column of `Sys.Admin.Lusid.Provider.Configure` is empty on success. On failure nothing is saved, and `Error` explains why (see [Appendix D](/docs/how-do-i-read-and-write-quote-metadata-fields-using-luminesce#appendix-d-configuration-errors)). If the new configuration drops a column that was configured before, the query also returns a warning listing the columns the providers will stop returning. Shortly after a successful configuration, the providers re-register with the new columns. You may need to select the refresh button in the Luminesce catalog to see them. ## How the providers change Once you configure metadata fields: - `Lusid.Instrument.Quote` returns one extra column per configured field, after the standard quote columns. - `Lusid.Instrument.Quote.Writer` accepts the same columns in its `ToWrite` table and returns them in its results, after the standard quote columns and before `WriteAction` and the write result columns such as `WriteErrorCode` and `WriteErrorDetail`. - If a quote has no value for a field, its column is `null`. - Fields marked `IsMain` are returned by `select ^`. - If you delete a field from the schema after configuring it, the column stays on the providers but is always `null`. Filtering on it doesn't fail, but writing a value to it does (see [Writing metadata fields](/docs/how-do-i-read-and-write-quote-metadata-fields-using-luminesce#writing-metadata-fields)). Run `Sys.Admin.Lusid.Provider.Configure` with `Remove`, or with `Set` and no `Configuration` table, to drop the column. The number of configured metadata fields has no meaningful effect on query performance. LUSID always returns every quote's metadata field values when it lists quotes. Configuring fields only exposes those values as columns, and doesn't trigger extra calls to fetch them. ## Reading and filtering quotes The following examples use the fields defined above, configured with their default column names. To list quotes with their metadata fields: ```sql select InstrumentId, QuoteEffectiveAt, Value, Unit, Vendor, AssetClass, VendorScoreRank from Lusid.Instrument.Quote where QuoteScope = 'my-quotes'; ``` You filter on metadata field columns like any other column: ```sql select InstrumentId, Value, Vendor, AssetClass from Lusid.Instrument.Quote where QuoteScope = 'my-quotes' and Vendor in ('bbg', 'refinitiv') and AssetClass = 'Equity'; ``` Field names that contain `.` or `/` need no special handling. You filter on the column name: ```sql select InstrumentId, VendorScoreRank from Lusid.Instrument.Quote where QuoteScope = 'my-quotes' and VendorScoreRank like 'A%'; ``` To find quotes with no value for a field: ```sql select InstrumentId, Value from Lusid.Instrument.Quote where QuoteScope = 'my-quotes' and Vendor is null; ``` ## Writing metadata fields To write metadata field values, include the metadata field columns in the table of data you pass to `Lusid.Instrument.Quote.Writer`: ```sql @quotes = select 'my-quotes' as QuoteScope, 'Client' as Provider, '' as PriceSource, 'my-instrument-1' as InstrumentId, 'ClientInternal' as InstrumentIdType, 'Price' as QuoteType, 'mid' as Field, #2024-01-01# as QuoteEffectiveAt, 101.0 as Value, 'GBP' as Unit, 'bbg' as Vendor, 'Equity' as AssetClass, 'A+' as VendorScoreRank, 'Upsert' as WriteAction union all select 'my-quotes', 'Client', '', 'my-instrument-2', 'ClientInternal', 'Price', 'mid', #2024-01-01#, 102.0, 'GBP', 'refinitiv', null, null, 'Upsert'; select * from Lusid.Instrument.Quote.Writer where ToWrite = @quotes; ``` The results return the metadata field values that were sent for each quote. Note the following: - **An upsert replaces the whole quote.** LUSID identifies a quote by its quote series (`Provider`, `PriceSource`, `InstrumentId`, `InstrumentIdType`, `QuoteType` and `Field`) and its `QuoteEffectiveAt`. Upserting a quote that already exists writes a complete new version of it. Every field, including `Value`, `Unit`, `ScaleFactor`, `Lineage` and the metadata fields, comes from the row you write. Nothing is carried over from the previous version, so a column you leave `null` doesn't keep its earlier value. For example, re-upserting `my-instrument-1` with `Vendor` set to `null` and `AssetClass` set to `'Fixed Income'` leaves the quote with only `AssetClass`. - `null` **means no value.** Luminesce doesn't send a `null` metadata field to LUSID, so the new version of the quote has no value for that field. - **Earlier versions are kept.** Quotes are bitemporal, so you can still see the version from before an upsert by querying `Lusid.Instrument.Quote` with an earlier `AsAt`. - **Each quote succeeds or fails on its own.** If a quote has a value for a configured column whose field has been removed from the schema, that quote fails and `WriteErrorDetail` names the field. Other quotes in the same write still succeed. - **Deleting a quote removes its metadata.** When `WriteAction` is `Delete`, Luminesce ignores the metadata field columns. To see which quotes failed: ```sql @response = select * from Lusid.Instrument.Quote.Writer where ToWrite = @quotes; select InstrumentId, WriteErrorCode, WriteErrorDetail from @response where WriteErrorCode <> 0; ``` ## Appendix A: Configuration columns | **Column** | **Meaning for metadata fields** | **If not supplied** | | --- | --- | --- | | `Key` | The metadata field name, exactly as defined, for example `Vendor.Score/Rank`. Case-sensitive. | Required whenever you pass a `Configuration` table. | | `Name` | The column name on the providers. | The field name in PascalCase (see [Appendix C](/docs/how-do-i-read-and-write-quote-metadata-fields-using-luminesce#appendix-c-column-names)). | | `DataType` | The Luminesce column type. | Taken from the field's data type (`Text` for string fields). | | `Description` | The column description shown in the catalog. | The field's description. | | `IsMain` | Whether `select ^` returns the column. | `False` | The `AsAt` column has no effect on metadata fields. `Sys.Admin.Lusid.Provider.Configure` always reads the latest field definitions. ## Appendix B: Write actions | `WriteAction` | **With a** `Configuration` **table** | **Without a** `Configuration` **table** | | --- | --- | --- | | `Set` (default) | Replaces the configuration with exactly the supplied fields. | Replaces the configuration with every field in the schema. | | `Modify` | Adds the supplied fields. If a supplied field is already configured, the new entry replaces the old one. Other configured fields stay as they are. | Adds any schema fields that aren't configured yet, and leaves existing columns exactly as configured. | | `Remove` | Removes the supplied fields from the configuration. | Not allowed. You must supply the fields to remove. | | `Reset` | Not applicable. | Deletes the configuration, so the providers go back to their standard columns. | ## Appendix C: Column names If you don't supply a `Name`, the column is named after the field in PascalCase, with any characters that aren't letters or digits removed: | **Field name** | **Default column name** | | --- | --- | | `vendor` | `Vendor` | | `assetClass` | `AssetClass` | | `Vendor.Score/Rank` | `VendorScoreRank` | Note the following: - A column name must start with a letter or underscore, and contain only letters, digits and underscores. - A column name can't duplicate another configured column, or one of the providers' standard columns such as `Value`, `Unit`, `Provider`, `QuoteScope` or `WriteAction`. The comparison ignores case. If a field's default name clashes, supply a `Name` for it. ## Appendix D: Configuration errors | **Situation** | **Error** | | --- | --- | | The key isn't a field in the schema | `The metadata field '<name>' does not exist in the quote market data field configuration. Please correct or remove the key.` | | No metadata fields are defined | `There are no quote metadata fields defined to configure. Add them to the quote market data field configuration first.` | | The column name isn't a valid identifier | Contains `Column name '<name>' for metadata field '<field>' is not valid.` | | The column name duplicates another column | `Duplicate column names, or names matching the provider's base columns, found in configuration for: <names>.` | | `Remove` without a `Configuration` table | `The metadata fields to remove must be supplied in 'Configuration'.` |