Overview
DALP produces an issuer's shareholder list itself: after every trade of an auction cycle is final, at the close of the last trading day of each month for securities that trade continuously, and again after a bust. It stores the list for the issuing organisation and emails the issuer's owners, as Have the platform deliver the list to the issuer describes. Each list covers one security at one record block, the chain block whose balances the list reports. Every holder's balance in the list is the on-chain balance after that block.
Use the manual export to read a list on demand, or to produce the month-end list yourself on a deployment that switched the month-end trigger off.
Choose when to run it
The record block must be final. DALP returns an error for a block later than the newest final block, so the balances at the record block do not change after you send the list. A later bust can still supersede the list, as Corrections describes. Leave the record block out to use the newest final block. The answer names the block it used.
Export from the Console
- Open the security, go to “Holders” and select Export in the table toolbar.
- Select Holder register…. The sheet opens at the block entered in “As of” on the Holders tab. For a past date it opens at the last final block at or before that date, and shows both. Otherwise it opens at the newest final block. Choose “Block” to enter another record block.
- Read the record block and its time, the number of holders, the units held and the total supply. The sheet uses the class-neutral words holder and units because it also lists stablecoins and deposit tokens.
- Check that Adds up shows “Yes”.
- Choose the Format, which is CSV by default. The download button names the format, as in “Download CSV”, “Download XLSX” or “Download PDF”. The file is read at the record block shown in the summary.
Export shows the register only to organisation owners, platform administrators, and accounts with the Permission manager, Auditor, Compliance manager or System manager role. Everyone else sees “This table as CSV”, which exports the rows and filters on screen.
Export with the Platform API
Read the totals first:
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>?atBlock=<recordBlock>" \
-H "X-Api-Key: <your api key>"The answer carries the totals at the record block:
{
"data": {
"chainId": 1,
"tokenAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"name": "Example Share",
"symbol": "EXS",
"decimals": 18,
"recordBlock": "1200",
"finalBlock": "1240",
"recordedAt": "2026-09-30T23:59:48.000Z",
"balancesSince": "2026-01-15T09:30:00.000Z",
"holderCount": 12,
"sharesHeld": "1000",
"totalSupply": "1000",
"reconciled": true,
"ownershipBasis": "on-chain-register",
"formats": ["csv", "xlsx", "pdf"]
},
"links": {
"self": "/api/v2/reporting/shareholder-lists/0x71C7656EC7ab88b098defB751B7401B5f6d8976F?atBlock=1200"
}
}data.reconciled is true when the holders' balances add up to data.totalSupply. data.recordBlock is the block the list is read at, and data.finalBlock is the newest final block. data.holderCount counts the holders, and data.sharesHeld is the units they hold. A refused read answers DALP-0753, with the reasons in When DALP cannot produce the list.
Then download the file at that same block. format is csv, xlsx or pdf:
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/download?atBlock=<recordBlock>&format=csv" \
-H "X-Api-Key: <your api key>" \
-o shareholder-list.csvTo read a list as of a date, first resolve the date to a block. The call answers with the last final block whose time is at or before the time you give, on the network of the request. A time after the newest final block gives the newest final block. A time before the network's first block gives record.
curl "https://your-instance.example.com/api/v2/reporting/record-blocks?at=2026-09-30T23:59:59Z" \
-H "X-Api-Key: <your api key>"{
"data": {
"chainId": 1,
"at": "2026-09-30T23:59:59.000Z",
"recordBlock": "1200",
"recordedAt": "2026-09-30T23:59:48.000Z",
"finalBlock": "1240"
},
"links": {
"self": "/api/v2/reporting/record-blocks?at=2026-09-30T23%3A59%3A59.000Z"
}
}The answer carries recordBlock, recordedAt, which is the time of that block, finalBlock and chainId. Pass recordBlock as atBlock on the totals and download calls.
Pass atBlock on the download even when you left it out of the first request. The newest final block moves as the chain grows, and a fixed block keeps the file equal to the totals you checked.
Check the list before you send it
- Adds up must be “Yes”, or
reconciledmust betrue. A “No” means the holders' units do not add up to total supply at the record block, so the list is incomplete or the balance history has not caught up. Do not send it. Read the list again later, and contact support with the security and the record block if it still shows “No”. - The number of holders should match the investors you expect after the auction or month.
Send the list
Deliver the CSV or XLSX file through the channel agreed with the issuer, with the PDF as the record of what was sent. Keep the security address and the record block with the sent file, so that the same list can be produced again.
Exchange the register with the Registrar
The Registrar is the issuer's registrar or transfer agent, the party outside DALP that keeps the issuer's register of members. DALP writes the holders in the Registrar's layout and compares the Registrar's own file with the chain. Both steps run on the “Registrar file” tab of the Console's export sheet or through the Platform API, and both read one record block.
Export shows the Registrar file only to organisation owners, platform administrators, and accounts with the Permission manager, Auditor, Compliance manager or System manager role. Every other account sees only “This table as CSV” in the menu.
Export the Registrar file from the Console
- Open the security, go to “Holders”, and select “Export” › Registrar file…. The sheet “Export holder register” opens on its “Registrar file” tab.
- Set the record block on the Register tab, where “As of” offers “Newest final block”, “Block” with a block number field, and “Date”. The Registrar file tab exports the block the register was read at. Both buttons on the Registrar file tab stay unavailable until the register answers for a block.
- Return to the “Registrar file” tab and select Export registrar file. The browser saves
registrar-.file- <symbol>- <block>. csv
The file has the columns holderWallet, identityReference, jurisdiction and quantity, one row per wallet holding a balance, sorted by wallet. The holder is identified by wallet address, and quantity is in the security's own units, for example 250.5 for a security with two decimals.
Export the Registrar file with the Platform API
Download it at a fixed block:
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/registrar-file?atBlock=<recordBlock>" \
-H "X-Api-Key: <your api key>" \
-o registrar-file.csvLeave atBlock out to read the newest final block. Pass it to keep the file equal to the register you checked, because the newest final block moves as the chain grows.
Reconcile a Registrar file from the Console
- Set the record block on the “Register” tab the same way, then open Registrar file.
- Select Reconcile registrar file and choose the Registrar's CSV file.
- Read the answer. The badge reads “Matches the chain at block” or “Does not match the chain at block” with the block, and beneath it the count of each result and the totals “Registrar file total”, “On-chain total” and “Total supply” in the security's units.
- The table under the summary lists every wallet that did not match, with the result, the quantity the file lists and the quantity on chain. A matched wallet opens no row.
An organisation owner or a platform administrator also writes each difference to the custody reconciliation break register. Any other reader gets the same comparison and records nothing.
When the file cannot be read, the alert “The registrar file could not be read” names the problem and the line, and nothing is compared.
Reconcile a Registrar file with the Platform API
Send the Registrar's file back to compare it with the chain at a block. The fileData field is the CSV text, with a header row that names at least holderWallet and quantity:
curl -X POST "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/registrar-reconciliations" \
-H "X-Api-Key: <your api key>" \
-H "Content-Type: application/json" \
-d '{"atBlock": "<recordBlock>", "fileData": "holderWallet,quantity\n0x1111111111111111111111111111111111111111,600\n"}'When the file is read, data._tag is Reconciled and every wallet has an outcome:
data.reconciled is true only when every row matched and the file total and the on-chain total both equal data.totalSupply.
When the file cannot be read, data._tag is Rejected, nothing is compared, and data.refusal names the problem (empty-file, unterminated-quote, malformed-quote, missing-column, invalid-wallet, invalid-quantity or duplicate-wallet) with data.line and data.value. Fix the file and send it again.
Look through nominee wallets to their beneficial owners
A nominee, custodian or broker can hold a security in one wallet for many beneficial owners. On chain that wallet is one holder. The nominee declares the owners behind the wallet, and readers of the shareholder list can then read the register looked through to those owners. Deliveries, the Registrar file and dividend payouts keep counting the on-chain register. A dividend read can still report each owner's share of the nominee's payout.
Declare and read them in the Console
- Open the security, go to “Holders” and select “Export” › Beneficial owners…. The sheet “Export holder register” opens on its “Beneficial owners” tab. Set the record block on the “Register” tab first: the tab declares and reads at that block, and “File declaration” stays unavailable until the register answers for a block.
- Under “Declare beneficial owners”, enter the “Nominee wallet”, select “Choose CSV file” and pick a file with the columns that Declare the owners behind a wallet lists. Select File declaration.
- A filed declaration shows Declaration filed at block with the nominee wallet, the owners and units declared, and whether the identities were stored encrypted or were not in the file. A refused one shows “The declaration was not filed” with the reason, the line and the column of the problem. Nothing is stored. A wallet that is not an address is refused before anything is sent.
- Under Register by beneficial owner, read the register at the record block: whether it adds up to the total supply, the number of entries, the wallets looked through and the stale wallets. The table has one row per direct holder, declared owner or stale wallet, and “Holding” filters to one kind. The identity columns (“Legal name”, “ID type”, “ID number”, “Investor category”) show only when the register returned them. A stale wallet shows “Stale” on a highlighted row, listed whole, with a notice that a new declaration at a later block looks through it again.
- Select Export in the table toolbar to download the rows on screen as CSV, including the identity columns when they are shown.
The Console reads the register only while the “Beneficial owners” tab is open, because every read is recorded in the audit trail. A member files a declaration for a wallet it holds. The organisation owner or a platform administrator can file for any wallet.
Declare the owners behind a wallet
The nominee sends one declaration per security and wallet, for one block. fileData is CSV text with the header owner:
ownerReferenceis the nominee's own reference for the owner: 1 to 64 printable characters without spaces, unique in the file.jurisdictionis the owner's ISO 3166-1 alpha-2 country, such asAE.quantityis the units held for the owner, in the security's own units, above zero.
Four optional columns add each owner's identity. Leave them all out and the declaration is exactly ownerReference, jurisdiction and quantity. If the header has any of them it must have legalName, and then every row needs a legalName:
legalNameis the owner's legal name, at most 200 characters, with no control characters.idTypeis one ofpassport,national_id,drivers_license,tax_id,company_registrationorlei. Leave it empty for a row without an ID. A row with anidTypeneeds anidNumber, and the other way round.idNumberis the number or registration code, 1 to 64 printable characters without spaces.investorCategoryis one ofretail,professional,institutionaloreligible_counterparty, or empty.
curl -X POST "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/beneficial-owner-declarations" \
-H "X-Api-Key: <your api key>" \
-H "Content-Type: application/json" \
-d '{"nomineeWallet": "<wallet>", "atBlock": "<block>", "fileData": "ownerReference,jurisdiction,quantity\nC-1,AE,600\nC-2,SA,400\n"}'Leave atBlock out to declare at the newest final block. A file holds at most 5000 owners.
A member of the organisation declares for a wallet it holds. The organisation owner or a platform administrator can declare for any wallet, for example from a file the nominee sent. Any other caller is answered as not found.
The declaration is stored only when its quantities add up to the wallet's balance at the block. Then data._tag is Declared, with the declaration's id, asOfBlock, ownerCount and total. Otherwise data._tag is Rejected, nothing is stored, and data.refusal names the problem:
Declarations are never changed. Sending the same file for the same wallet and block again answers with the stored declaration. A file that differs only in its identity columns counts as a different declaration.
How the identities are kept
The identity columns are sealed with envelope encryption in the platform database, as one envelope per declaration. They never go on chain, into email, webhooks or indexer data. The declaration's answer does not repeat them: data.withIdentities says whether the file carried them. The owner reference, country and units stay readable as before.
Only reporting readers can read the identities back, through the looked-through register: the organisation owner, holders of the Permission manager, Auditor, Compliance manager or System manager role, and a platform administrator, who runs the platform and reaches every organisation. A member who only files for its own wallet cannot read the identities back, and every read is recorded in the audit trail.
Read the looked-through register
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/beneficial-owners?atBlock=<recordBlock>" \
-H "X-Api-Key: <your api key>"Reading needs the same access as the shareholder list, and every read is recorded in the audit trail. Each row has a basis:
A declared row also carries legalName, idType, idNumber and investorCategory when its declaration had identity columns. They are null on direct and stale rows, on declarations filed without identities, and for an idType, idNumber or investorCategory the file left empty.
data.reconciled is true when the rows add up to data.totalSupply. data.ownerCount counts the rows, so two nominees' owners count separately even when they are the same person. data. and data.staleWallets count the wallets split into owners and the wallets left whole as stale.
Read a dividend's entitlements per beneficial owner
To see what each declared owner of a nominee wallet is due from a dividend, name the dividend instead of a block:
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/beneficial-owners?dividendId=<dividendId>" \
-H "X-Api-Key: <your api key>"The register is read at the dividend's record block, so atBlock is not accepted together with dividendId. The dividend must have its record-date snapshot computed. Otherwise the call answers not found, with the resource dividend. A dividend of another security answers the same way.
Each row gains entitlement, in the payout asset's own units (data. and data.):
- A
declaredrow holds the owner's share. It applies the dividend's own per-unit rule,units × amountrounded down, to the owner's units from the declaration.Per Share ÷ one whole unit - A
directorstalerow holds the wallet's own entitlement, exactly what the dividend pays that wallet.
data.dividend.nominees lists each wallet that was split. Its entitlement is the one amount the dividend pays the wallet on chain, allocated is the owners' shares added up, and unallocated is the rounding remainder. The owners' shares plus unallocated always equal entitlement, to the unit. A wallet with a stale or no declaration is not split and not listed. When the dividend pays the wallet less than the owners' shares add up to, as for units the issuer's treasury holds, no owner gets a share and the whole amount is unallocated.
This is a report only. The nominee is still paid on chain as one entitlement and claims it once. The dividend's Merkle root, its approval fingerprint and its payout do not change, and nothing is claimed per owner. Without dividendId, entitlement and data.dividend are null.
Have the platform deliver the list to the issuer
With the triggers on, skip the export and the handoff. The platform produces the list itself, stores the CSV, XLSX and PDF editions, and mails the issuing organisation that the list arrived. Each delivery is bound to one record block.
What starts a delivery
Four triggers create a delivery:
auction-settled: the platform opens it once every auction trade of the security has settled, no fill is still waiting to settle, and no settled trade still waits for delivery, at the highest settled fill block or later delivery block. This covers auction-only instruments, including those with a holding period.month-end: the platform opens it for each continuous-book security after the last trading day of a month closes. The delivery records that trading day. Month-end lists and defaults lists the settings.correction: the platform opens it after a bust reverses a settled trade that a delivered list counted. See Corrections.scheduled: you open it when you post a record block through the Console or the Platform API.
A delivery stays pending until its record block is final. A scheduled pass produces each delivery whose block is final. One record block holds one delivery: posting a block that already has one returns that delivery, whichever trigger created it. A delivery whose holders' balances do not add up to total supply also stays pending: the pass records an attempt and a last error, writes no files, sends no mail, and writes no outcome audit until the projection reconciles.
Month-end lists and defaults
A continuous-book security gets its month-end list without any action from you. The platform finds the last trading day of the month, waits for the cut-off, and opens a delivery at the record block. A month stays eligible for 35 days plus the cut-off grace period, so a month missed during a platform outage is still delivered when the platform recovers. After that window the platform opens no month-end delivery for the month. Post its record block yourself, as Schedule with the Platform API describes. A month that already has a delivery opens no second one.
The last trading day is the last session occurrence in the instrument's local calendar month. Collection windows do not count. The cut-off is the session close plus a grace period. The platform opens the delivery only when the session is closed, no trade is waiting to settle, and no fill is queued.
Set a boolean setting to false to switch the trigger off. The auction trigger has no setting and is always on. The grace period and the lookback take durations. The timezone takes an IANA name such as Asia/Dubai. When you switch the month-end trigger off, run it by hand as the Choose when to run it table describes. Corrections have no manual equivalent.
Corrections
A bust can reverse a trade that an earlier list counted. When it does, the platform opens a correction delivery on its own. You do not post it.
- The correction supersedes the newest delivered list that counted the trade. It is recorded at the latest final block and carries the reason
bust. - Only a bust inside the lookback window is considered, and only a trade settled at or before the list's record block and busted after it. The correction waits until the final block is newer than the bust.
- The earlier edition stays downloadable. Its row shows Superseded and names the list that replaces it. The correction row shows “Correction”, “Reason: trade bust”, and the block it replaces.
- In the API,
supersedesIdon the correction andsupersededByIdon the earlier list point at each other.correctionReasonisbust. - A newer bust against a correction supersedes that correction in turn. One correction exists per superseded list.
- The issuer's owners get the usual delivery email. It names the corrected record block and the reason, and carries no holder data.
When REPORTING_ is false, the platform opens no correction, and no manual step creates one. A list you schedule is an ordinary scheduled list: it does not carry the correction trigger or the reason bust, and it does not mark the earlier list as superseded. If you still want the issuer to have a list after a bust, schedule one at the newest final block that is later than the bust, and tell the issuer which list replaces which.
Ownership basis
The list is the on-chain register: every wallet that holds the security at the record block. Each delivery is stamped with ownershipBasis on-chain-register, and the PDF prints it under the record block. The summary of an on-demand read carries the same field. A custodian's shared wallet appears as one holder under the custodian's wallet. The list does not look through to the custodian's investors, so the issuer needs the custodian's own records for those.
Schedule from the Console
- Open the security, go to “Holders” and select “Export” › Holder register….
- Choose Block and enter the record block, or keep the newest final block.
- Select Deliver to issuer. The sheet moves to “Deliveries”.
“Export” › Issuer deliveries… opens the same tab. The table shows each delivery with its record block, trigger, status, delivered time, holder count and downloads. The trigger reads “After auction”, “Requested”, “Month end” or “Correction”. “Requested” is a list an operator asked for by hand, which the API calls the scheduled trigger. A pending row reads “Waiting” and refreshes while the pass produces it. A delivered row offers one download per format. A refused row names the reason.
Schedule with the Platform API
Post the record block as a string:
curl -X POST "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/deliveries" \
-H "X-Api-Key: <your api key>" \
-H "Content-Type: application/json" \
-d '{"recordBlock": "1200"}'The platform answers with the delivery. A block past the newest final block stays pending until the block is final.
A security your organisation does not hold answers 404 with code reporting.. That answer covers a missing security, a security of another organisation, and a security with no resolvable issuer. Your organisation learns nothing about other organisations from it.
List deliveries
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/deliveries?offset=0&limit=50" \
-H "X-Api-Key: <your api key>"The newest record block comes first. limit takes 1 to 200 and defaults to 50, and a larger value is refused as invalid. meta.total counts every delivery of the security in your organisation, meta.canSchedule says whether you may schedule one, and links pages through the list:
{
"data": [
{
"id": "0199b2d1-8a19-7a08-8d21-4d33e3c1a111",
"chainId": 1,
"tokenAddress": "0x0000000000000000000000000000000000000001",
"recordBlock": "900",
"trigger": "auction-settled",
"ownershipBasis": "on-chain-register",
"supersedesId": null,
"supersededById": null,
"tradingDay": null,
"correctionReason": null,
"status": "delivered",
"requestedBy": null,
"attempts": 1,
"lastError": null,
"createdAt": "2026-10-10T08:05:00.000Z",
"settledAt": "2026-10-10T08:10:00.000Z",
"holderCount": 12,
"refusal": null,
"notice": "sent",
"noticeAttempts": 1,
"parts": {
"csv": {
"objectKey": "shareholder-lists/org_a/0199b2d1-8a19-7a08-8d21-4d33e3c1a111.csv",
"digest": "9f2c4a7e1b5d83f06a2c9e4b7d105f3a8c6e2d4b9f105a3c7d2e6b8a1f4c5d6",
"contentLength": 1840
},
"xlsx": {
"objectKey": "shareholder-lists/org_a/0199b2d1-8a19-7a08-8d21-4d33e3c1a111.xlsx",
"digest": "41bd9c0e77f2a5d18c3e6b0a4f9d2c7e5b8a1f306d4c5e9b8a7f1c2d3e4a5b6c",
"contentLength": 6231
},
"pdf": {
"objectKey": "shareholder-lists/org_a/0199b2d1-8a19-7a08-8d21-4d33e3c1a111.pdf",
"digest": "c7e30bd4a19f6c2d5e8b40a173f5c9d6e2b80417f6a3c5e9d0b2f486a1c7d3e5",
"contentLength": 12904
}
}
}
],
"meta": { "total": 1, "canSchedule": true },
"links": {
"self": "/api/v2/reporting/shareholder-lists/0x0000000000000000000000000000000000000001/deliveries?offset=0&limit=50",
"first": "/api/v2/reporting/shareholder-lists/0x0000000000000000000000000000000000000001/deliveries?offset=0&limit=50",
"prev": null,
"next": null,
"last": "/api/v2/reporting/shareholder-lists/0x0000000000000000000000000000000000000001/deliveries?offset=0&limit=50"
}
}Download a stored edition
curl "https://your-instance.example.com/api/v2/reporting/shareholder-lists/<tokenAddress>/deliveries/<deliveryId>/download?format=csv" \
-H "X-Api-Key: <your api key>" \
-o shareholder-list-900.csvformat is required: csv, xlsx or pdf. The platform returns the stored bytes. A download of a pending delivery answers 503, as does a file whose bytes no longer match the recorded digest or length. A refused delivery never becomes available: a security-not-found or not-issuer refusal answers 404, a feature or history refusal answers 422 with code reporting., a file-unwritable refusal answers 500 with code reporting. (DALP-14085), a storage-refused refusal answers 500 with code reporting. (DALP-14088), and a chain-read-invalid refusal answers 500 with code core. (DALP-14108). None of these 500 answers is retryable. A delivery of another organisation answers 404.
How the issuer learns that the list arrived
The platform emails every owner of the issuing organisation when a delivery is delivered or refused. The mail names the security, the record block and the trigger, states the reason when refused, and links to the security page in the Console. It carries no holder data.
A notice that fails to send retries on later passes after a backoff, up to three attempts, then stays failed. The wait is 10 minutes after the first failure and 20 minutes after the second. A retry only emails the owners who have not received that notice. Recipients who already received it are not emailed again. When mail is not configured, the notice stays not-configured. If the platform crashes after the mail transport accepts a notice but before that acceptance is recorded, the next pass may email that recipient again, so a recipient can receive the same notice twice.
Audit and retry
Each delivered delivery, refused delivery, sent notice and failed notice writes an operations audit row for the issuing organisation. You read those rows through the reporting audit trail. The audit trail also records who made the schedule call and each download.
A short-lived failure leaves the delivery pending with an attempt count and a last error, and a later pass retries it after a backoff. The wait starts at 5 minutes and doubles with each attempt, up to 24 hours. An unreconciled list waits the same way: it stays pending with an attempt and a last error, and a later pass delivers it once the holders add up to total supply. A failure that gives the same result on every attempt does not wait: a list that cannot be written in one of its formats is refused as file-unwritable on the first attempt. A refused delivery is terminal and never retries.
A delivery whose stored record is damaged is skipped and counted, and the pass carries on with the other deliveries. The damaged delivery is neither produced nor emailed, and a read that needs it answers temporarily unavailable rather than returning partial data. An audit event whose stored record is damaged is skipped the same way and is missing from the reporting audit trail, while the delivery's other audit events are still recorded. Contact support with the security and the record block.
When a delivery is refused
A block past the newest final block never refuses a delivery, and neither does an unreconciled list. Both wait as pending: the delivery for a block past the newest final block until that block is final, and the delivery for an unreconciled list until the projection reconciles.
Systems that organisations share
The platform names the issuing organisation from the system the security lives in. When one organisation holds the system, that organisation is the issuer. When organisations share the system, the recorded issuer is the issuer only while it still holds the system. A missing recorded issuer, or one that no longer holds the system, names no issuer: the security gets no auction delivery, and scheduling answers not found.
What the file contains
The CSV and XLSX files have one row per wallet that holds the security after the record block, largest holding first. A wallet with a zero balance is left out. The PDF shows the same holders with the network and its chain ID, the record block and its time, and the reconciliation result. Its holders table ends with a totals row: the number of holders, the units they hold, and the share of supply those units are.
Where the chain records a field, the column maps to its field in the shareholder response of Commission Implementing Regulation (EU) 2018/1212, Annex Table 2, and to its entry in the register of members under section 118 of the ADGM Companies Regulations 2020. The file alone is not a complete shareholder response or register of members: it carries the contract address in place of an ISIN and no names or addresses, which the issuer completes from its own records.
In the XLSX file, recordDate and percentOfSupply are numbers. recordBlock is a number when it fits spreadsheet precision exactly, and text otherwise, so the block identifier cannot change. shares is a number only when every holder's balance and their sum fit a spreadsheet number exactly, which is 15 significant digits. Otherwise the whole column is text, so that no amount is rounded. A spreadsheet total of a text column is 0, so check the column type before you add it up. The CSV file holds text in every column.
The file does not hold names or postal addresses. The issuer matches each identity to the member's name and address in its own records.
When DALP cannot produce the list
A refused list returns DALP-0753 with a reason in data.reason: