FinchContext
Run with

Build a CRS Report XML (OECD Schema)

Skill: Convert reportable-account data into the OECD Common Reporting Standard XML

Region: Global (OECD Common Reporting Standard — automatic exchange of financial account information) Category: Tax — OECD CRS XML (Automatic Exchange of Information, AEOI) Does: Takes a financial institution's reportable-account data and produces the OECD CRS XML for submission to a tax authority and onward exchange — the reporting-FI block, account-holder and controlling-person records, account balances/payments, TIN handling, nil reporting, and corrections (DocRefId/CorrDocRefId). Schema version: OECD CRS XML Schema v3.0 (with MessageSpec, ReportingFI, ReportingGroup)

The AI assembles the XML from your data; it does not classify accounts or determine reportability. Per-jurisdiction TIN rules, residence determination, and onboarding due diligence are the FI's responsibility. Confirm your jurisdiction's CRS schema version and validation portal (many tax authorities add a local wrapper) before submission.


When this applies


Build procedure

  1. Read the source — account register: account number, balance, currency, account-holder identity (name, address, residence country, TIN, date of birth), account type, and payments by type (interest/dividends/gross proceeds/other).
  2. Build the message header (MessageSpec) — sending company IN, transmitting & receiving country, reporting period (year-end date), message type (CRS701), and a unique MessageRefId.
  3. Build the ReportingFI — the FI's name, address, residence country, and IN; set DocTypeIndic (OECD1 new data, OECD0 resend, OECD2/3 correction/void).
  4. Build each AccountReport — account number, DocRefId, account holder (Individual or Organisation) with ResCountryCode + TIN, controlling persons (for passive NFEs), account balance, and Payment blocks.
  5. Normalize — dates YYYY-MM-DD; ResCountryCode/currency as ISO codes; TIN with issuedBy; omit-reason codes where a TIN is unavailable.
  6. Assign DocRefIds — globally unique per record (<sending-country><year>-<uuid>); corrections reference the prior DocRefId in CorrDocRefId.
  7. Emit the CRS XML, per the worked example.
  8. Validate — work through the checklist.

Source → CRS field map

From the source → CRS element
Sending FI IN MessageSpec/SendingCompanyIN
Transmitting / receiving country MessageSpec/TransmittingCountry, ReceivingCountry
Reporting year-end MessageSpec/ReportingPeriod
Unique message reference MessageSpec/MessageRefId
FI name / address / IN ReportingFI/Name, Address, IN
Account number AccountReport/AccountNumber
Record reference AccountReport/DocSpec/DocRefId
Account-holder name AccountHolder/Individual/Name
Residence country .../ResCountryCode
Taxpayer ID .../TIN (issuedBy)
Date of birth Individual/BirthInfo/BirthDate
Account balance AccountBalance (currCode)
Payments Payment/Type + Payment/PaymentAmnt

Document structure (CRS)

CRS_OECD (version 3.0)
├── MessageSpec   (SendingCompanyIN, Transmitting/ReceivingCountry, MessageType,
│                  MessageRefId, ReportingPeriod, MessageTypeIndic)
└── CrsBody
    ├── ReportingFI   (ResCountryCode, IN, Name, Address, DocSpec)
    └── ReportingGroup
        └── AccountReport ...
            ├── DocSpec (DocTypeIndic, DocRefId[, CorrDocRefId])
            ├── AccountNumber
            ├── AccountHolder (Individual | Organisation + CtrlgPerson)
            ├── AccountBalance
            └── Payment ...

Code tables

Document type indicator (DocTypeIndic)

Code Meaning
OECD1 New data
OECD0 Resent data
OECD2 Corrected data
OECD3 Deletion of data
OECD10OECD13 Test-data equivalents

Message type indicator (MessageTypeIndic)

Code Meaning
CRS701 New information
CRS702 Corrections / deletions
CRS703 No data to report (nil)

Payment type

Code Meaning
CRS501 Dividends
CRS502 Interest
CRS503 Gross proceeds / redemptions
CRS504 Other (e.g. other CRS income)

TIN unavailable (TIN issuedBy + unknown) / omit reasons

Use the account-holder's residence-jurisdiction TIN. Where none exists, follow the schema's TIN unknown="true" handling and any local explanation field.


Calculation rules


Worked example (end-to-end)

Input — one reportable individual account

Holder: Maria Schmidt, resident DE, TIN DE0123456789, DOB 1980-05-12; account CH93-0000-0000-0000-1 balance €85,000.00; interest paid €1,250.00.

Output — CRS XML

<?xml version="1.0" encoding="UTF-8"?>
<CRS_OECD xmlns="urn:oecd:ties:crs:v3" version="3.0">
  <MessageSpec>
    <SendingCompanyIN>CHE123456789</SendingCompanyIN>
    <TransmittingCountry>CH</TransmittingCountry>
    <ReceivingCountry>DE</ReceivingCountry>
    <MessageType>CRS</MessageType>
    <MessageRefId>CH2025-2f1c9b40</MessageRefId>
    <MessageTypeIndic>CRS701</MessageTypeIndic>
    <ReportingPeriod>2025-12-31</ReportingPeriod>
  </MessageSpec>
  <CrsBody>
    <ReportingFI>
      <ResCountryCode>CH</ResCountryCode>
      <IN issuedBy="CH">CHE123456789</IN>
      <Name>Alpine Private Bank AG</Name>
      <Address>
        <CountryCode>CH</CountryCode>
        <AddressFree>Bahnhofstrasse 1, 8001 Zurich</AddressFree>
      </Address>
      <DocSpec>
        <DocTypeIndic>OECD1</DocTypeIndic>
        <DocRefId>CH2025-FI-0001</DocRefId>
      </DocSpec>
    </ReportingFI>
    <ReportingGroup>
      <AccountReport>
        <DocSpec>
          <DocTypeIndic>OECD1</DocTypeIndic>
          <DocRefId>CH2025-AR-0001</DocRefId>
        </DocSpec>
        <AccountNumber>CH9300000000000001</AccountNumber>
        <AccountHolder>
          <Individual>
            <ResCountryCode>DE</ResCountryCode>
            <TIN issuedBy="DE">DE0123456789</TIN>
            <Name>
              <FirstName>Maria</FirstName>
              <LastName>Schmidt</LastName>
            </Name>
            <Address>
              <CountryCode>DE</CountryCode>
              <AddressFree>Hauptstrasse 5, 10115 Berlin</AddressFree>
            </Address>
            <BirthInfo>
              <BirthDate>1980-05-12</BirthDate>
            </BirthInfo>
          </Individual>
        </AccountHolder>
        <AccountBalance currCode="EUR">85000.00</AccountBalance>
        <Payment>
          <Type>CRS502</Type>
          <PaymentAmnt currCode="EUR">1250.00</PaymentAmnt>
        </Payment>
      </AccountReport>
    </ReportingGroup>
  </CrsBody>
</CRS_OECD>

Validation checklist


Last updated: 2026-06-12 — confirm the CRS schema version (v2.0 vs v3.0), your jurisdiction's local wrapper/portal rules, and current TIN-omission handling before submission.