File format guide

sdn_advanced.xml: OFAC's advanced SDN list file, explained

sdn_advanced.xml is the richest machine-readable form of the US Treasury's SDN list: every designation published as normalized XML, including the digital-currency addresses, identity documents and party relationships the simpler formats flatten or drop. This page covers where to download it, how the schema is organized, and how to parse it — verified against the live file in August 2026.

What is sdn_advanced.xml?

The Office of Foreign Assets Control publishes its Specially Designated Nationals list in several formats. sdn_advanced.xml is the advanced-schema edition: the same designated parties as the basic sdn.xml — 19,199 records in both at the time of writing — but modeled relationally instead of flattened into one record per party. Names, addresses, documents and attributes live in separate structures that reference each other by ID, the way OFAC stores them internally.

That structure is why the file matters for crypto compliance: digital-currency addresses appear as typed features — twenty distinct types today, from Digital Currency Address - XBT and - ETH through USDT, TRX, SOL and DOGE — attached to the designated party that controls them, alongside reliability markers and the relationships between listed entities. The current file weighs in around 120 MB and carries a schema version of 3.

Where to download sdn_advanced.xml

The official host is sanctionslistservice.ofac.treas.gov — OFAC's Sanctions List Service, which took over file distribution from the legacy treasury.gov download paths. The download endpoint answers with a short-lived redirect to a signed file URL, so fetch it fresh each time rather than bookmarking the redirect target:

Older integrations may still point at www.treasury.gov/ofac/downloads/sanctions/1.0/sdn_advanced.xml. Those legacy paths currently issue 302 redirects to the Sanctions List Service, so they still resolve — but new code should call the sanctionslistservice.ofac.treas.gov endpoints directly. For one-off manual lookups, OFAC's Sanctions List Search queries the same data without any downloading.

Advanced vs basic SDN formats

Every format carries the same designations; they differ in how much structure survives. Pick by what you need to extract:

FileShapeWhat it carries
sdn.xmlFlat XML, one <sdnEntry> per partyNames, aliases, addresses, program tags and <id> entries — including Digital Currency Address types. Enough for direct screening.
sdn_advanced.xmlNormalized, relational XML (~120 MB)Everything in sdn.xml plus typed features with reliability markers, party-to-party relationships, full ID document records and the reference tables.
sdn.csv + add.csv + alt.csvThree CSVs keyed by entity numberNames, addresses and aliases split across linked files. Easiest to load into a database; least structure.
consolidated.xml / cons_advanced.xmlSame two XML schemasThe Non-SDN Consolidated Sanctions List equivalents. The same parsing code works on both.

The Non-SDN consolidated files document OFAC's separate Consolidated Sanctions List, and the EU publishes its own XML with a different schema entirely — see the EU consolidated sanctions list page for that format.

The OFAC advanced SDN schema

The root element is <Sanctions> in the …/exports/ADVANCED_XML namespace. Six top-level sections do the work — here is the path to a designated party's crypto address, abridged from the real record for the Lazarus Group (FixedRef 27307):

<Sanctions xmlns="https://sanctionslistservice.ofac.treas.gov/api/PublicationPreview/exports/ADVANCED_XML"
           Version="3">
  <DateOfIssue CalendarTypeID="1">…</DateOfIssue>

  <ReferenceValueSets>   <!-- lookup tables; everything below points here by ID -->
    <FeatureTypeValues>
      <FeatureType ID="344" FeatureTypeGroupID="1">Digital Currency Address - XBT</FeatureType>
      <FeatureType ID="345" FeatureTypeGroupID="1">Digital Currency Address - ETH</FeatureType>
      …
    </FeatureTypeValues>
  </ReferenceValueSets>

  <DistinctParties>      <!-- one DistinctParty per designated party -->
    <DistinctParty FixedRef="27307">
      <Profile ID="27307" PartySubTypeID="3">
        <Identity …>     <!-- names, as Alias → DocumentedName → NamePartValue -->

        <Feature ID="50215" FeatureTypeID="345">   <!-- 345 → Digital Currency Address - ETH -->
          <FeatureVersion ID="47914" ReliabilityID="1560">
            <VersionDetail DetailTypeID="1432">0x098B716B8Aaf21512996dC57EB0615e2383E2f96</VersionDetail>
          </FeatureVersion>
          <IdentityReference IdentityID="19011" IdentityFeatureLinkTypeID="1" />
        </Feature>
      </Profile>
    </DistinctParty>
  </DistinctParties>

  <ProfileRelationships>…</ProfileRelationships>  <!-- who owns / acts for whom -->
  <SanctionsEntries>…</SanctionsEntries>          <!-- program and legal basis per party -->
</Sanctions>
ElementWhat it holds
ReferenceValueSetsLookup tables for every coded value: alias types, country area codes, feature types (including the digital-currency address types), ID document types. The rest of the file references these by numeric ID.
DistinctPartiesOne DistinctParty per designated party. Its Profile carries the Identity (names and aliases) and the Features — typed attributes like digital-currency addresses, dates of birth, websites and email addresses, each with a reliability marker.
IDRegDocumentsIdentity documents as full records: passports, national IDs, tax and registration numbers, with issuing country and validity flags.
LocationsStructured addresses (parts keyed by type, with area codes), referenced from party features rather than embedded in them.
SanctionsEntriesThe designations themselves: which sanctions program and legal authority each party is listed under, with entry events and dates.
ProfileRelationshipsParty-to-party links — ownership and acting-for relationships between profiles, which the flat formats cannot express.

The practical consequence of the ID-reference design: you cannot read a party record in isolation. To know that FeatureTypeID 345 means an Ethereum address, you first index ReferenceValueSets — which is exactly how the parsing example below works.

Parsing sdn_advanced.xml in Python

At ~120 MB the file is too big to load as a DOM comfortably, so stream it. This example uses only the standard library: it indexes the digital-currency feature types from the reference tables (they appear before any party records), then walks each DistinctParty, pulling every listed address with its chain type and the party's primary name. It runs in about two seconds:

import xml.etree.ElementTree as ET

NS = "{https://sanctionslistservice.ofac.treas.gov/api/PublicationPreview/exports/ADVANCED_XML}"

crypto_types = {}  # FeatureTypeID -> "Digital Currency Address - ETH", ...
addresses = []

for _, elem in ET.iterparse("sdn_advanced.xml", events=("end",)):
    tag = elem.tag.removeprefix(NS)
    if tag == "FeatureType" and (elem.text or "").startswith("Digital Currency Address"):
        crypto_types[elem.get("ID")] = elem.text
    elif tag == "DistinctParty":
        name = next(
            (
                " ".join(v.text or "" for v in alias.iter(f"{NS}NamePartValue"))
                for alias in elem.iter(f"{NS}Alias")
                if alias.get("Primary") == "true"
            ),
            "",
        )
        for feature in elem.iter(f"{NS}Feature"):
            feature_type = crypto_types.get(feature.get("FeatureTypeID"))
            if feature_type is None:
                continue
            detail = feature.find(f"{NS}FeatureVersion/{NS}VersionDetail")
            if detail is not None and detail.text:
                addresses.append((feature_type, detail.text, name))
        elem.clear()  # keep memory flat: the file is ~120 MB

print(f"{len(addresses)} digital-currency addresses")
for feature_type, address, name in addresses[:3]:
    print(f"{feature_type}: {address}  ({name})")
977 digital-currency addresses
Digital Currency Address - TRX: TNiq9AXBp9EjUqhDhrwrfvAA8U3GUQZH81  (BANK MARKAZI JOMHOURI ISLAMI IRAN)
Digital Currency Address - TRX: TTiDLWE6fZK8okMJv6ijg42yrH6W2pjSr9  (BANK MARKAZI JOMHOURI ISLAMI IRAN)
Digital Currency Address - TRX: TAhwhFv3JpK39Nc2m8W5LPCcoTisutiRfp  (BANK MARKAZI JOMHOURI ISLAMI IRAN)

Real output from the August 7, 2026 publication: 977 listed digital-currency addresses. Swap ElementTree for lxml.etree and the same code runs faster; extend the feature-type filter to pull email addresses and websites, or walk IDRegDocuments for passports and registration numbers.

Update cadence: the part that hurts

OFAC publishes on no fixed schedule — designations, amendments and removals land as enforcement actions happen, sometimes several times a week. Each publication replaces the files wholesale: there is no incremental diff to download. A production pipeline therefore has to poll for new publications, re-download ~120 MB, re-parse, and reconcile against what it stored last time — including removals, because screening against a stale copy flags parties that have been delisted (Tornado Cash's addresses, removed in March 2025, are the canonical example).

Parsing the file once, as above, is an afternoon. Running that loop reliably forever — with monitoring, delisting reconciliation and an audit trail — is the actual cost of building on the raw files.

Skip the parsing: query the same data via API

CompliAPI runs that pipeline as a service: OFAC's SDN publication stream is re-ingested every 15 minutes, delistings are tracked, and the identifiers the advanced schema carries — digital-currency addresses, emails, websites, government IDs — become one authenticated GET request each. The same Lazarus Group address extracted above, screened live, with the official source record on the match:

GET /api/v1/screen/crypto/{address}

curl https://api.compliapi.com/api/v1/screen/crypto/0x098B716B8Aaf21512996dC57EB0615e2383E2f96 \
  -H "Authorization: Bearer $COMPLIAPI_TOKEN"

Response

{
  "value": "0x098b716b8aaf21512996dc57eb0615e2383e2f96",
  "flagged": true,
  "sanctioned": true,
  "lists_checked": ["ofac", "us_fbi_lazarus_crypto", "il_mod_crypto", "fr_tresor", "jp_mof_sanctions", "uk_fcdo_sanctions"],
  "matches": [
    {
      "list": "ofac",
      "list_name": "US OFAC SDN",
      "list_type": "sanctions",
      "match": "exact",
      "value": "0x098B716B8Aaf21512996dC57EB0615e2383E2f96",
      "source_url": "https://sanctionssearch.ofac.treas.gov/Details.aspx?id=27307",
      "metadata": {
        "symbol": "ETH",
        "name": "Ethereum",
        "sdn_name": "LAZARUS GROUP",
        "sdn_type": "Entity",
        "programs": "DPRK3"
      }
    }
  ]
}

There is a free tier, and the OFAC API covers the non-crypto identifiers in the same records. All screening data sources

Screen against live SDN data

Get a free API key and check your first identifier in minutes — no XML required.

14-day free trial. No credit card required.