Skip to main content

ofac-sdn-parser

Fetch and parse the U.S. Treasury OFAC SDN list into crypto addresses. No API key, no account — the export is public.

import asyncio
from ofac_sdn_parser import fetch_sanctioned_addresses

rows = asyncio.run(fetch_sanctioned_addresses())
print(len(rows))                       # ~990
print(rows[0].address, rows[0].network, rows[0].entity_name, rows[0].program_label)
pip install git+https://github.com/omnitraceapp/ofac-sdn-parser
python -m ofac_sdn_parser.verify              # counts + per-chain breakdown + digest
python -m ofac_sdn_parser.verify --json       # machine-readable
python -m ofac_sdn_parser.verify --file SDN_ENHANCED.XML   # diff against a downloaded export

Why this exists

Every guide older than mid-2026 points at an endpoint that no longer works, and the two failures that follow are easy to make and hard to notice — both of them look like "OFAC has no crypto addresses today".

1. The old endpoints are gone. Verified 2026-09-06:

URL status
sanctionslist.ofac.treas.gov/api/sdn (old JSON API) 403 Forbidden
www.treasury.gov/ofac/downloads/sdn.xml (legacy) 302 to the new service
sanctionslistservice.ofac.treas.gov/api/PublicationPreview/exports/SDN.XML 200

The working URL redirects once more to a signed S3 object. Any HTTP client that follows redirects is fine.

2. Element.iter() silently returns nothing. The export uses a default XML namespace. Python's iter() does plain string matching and does not honour the {*} wildcard; only the ElementPath methods do.

root.iter("{*}sdnEntry")      # -> nothing, no error
root.iterfind("{*}sdnEntry")  # -> works

That one costs an afternoon if you hit it, and it fails quietly — you get an empty list, not an exception.

Proving a parse is complete

Non-empty is not the same as complete. address_set_digest() is an MD5 over the sorted, de-duplicated address set: compute it over your output and over Treasury's own export, and if the two agree you are reading the same list.

from ofac_sdn_parser import address_set_digest
print(address_set_digest(rows))

The bundled verifier does this for you and prints the per-chain breakdown:

addresses:        991
  bitcoin        536
  tron           282
  ethereum       124
  unknown         27
  litecoin        12
  dash             5
  zcash            4
  xrp              1
sdn entries read: 19,329
duplicates:       16
skipped (blank):  0
digest (md5):     3c29b9cfef715f206bcb8c8ec8dd8356

That is a real run against the live feed on 6 September 2026. The digest is not a constant to match - OFAC designates and delists continually, so it changes. It is a fingerprint for comparing two parses of the same download.

Notes worth knowing

  • Do not switch to SDN_ENHANCED.XML. It is 103 MB against 28 MB and contains exactly the same addresses — the extra content is entity metadata and ownership relationships, not more wallets.
  • OFAC publishes deltas. /changes/latest is ~15 KB against the 28 MB full export, and /changes/history/{year}[/{month}[/{day}]] lists publication ids. Crypto designations are rare — roughly one publication in eight carries any. Deltas use the namespace https://www.treasury.gov/ofac/DeltaFile/1.0 and mark each entity action="add" / "remove".
  • skipped_blank should be zero. A crypto row with a valid idType and no idNumber means the schema moved and addresses are being dropped. The parser reports the count instead of swallowing it.
  • network is unknown rather than a guess. A wrong chain label sends a lookup to the wrong explorer, which is worse than no label.
  • An absence of match is not a clean result. OFAC covers US-designated entities and nothing else.

Install

pip install git+https://github.com/omnitraceapp/ofac-sdn-parser

Not on PyPI yet. Requires Python 3.10+ and aiohttp — though parse_sdn_xml itself is pure and needs neither, so you can vendor the one file if you already have the XML.

Tests

pip install -e ".[dev]"
pytest

The suite runs against a bundled fixture and makes no network calls.

Licence

MIT.


Maintained by OmniTrace, which tracks USDT and USDC blacklist events on TRON and Ethereum and screens wallets against this list. The same parser runs in production there; measured statistics are published here.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ofac_sdn_parser-1.0.0.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ofac_sdn_parser-1.0.0-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file ofac_sdn_parser-1.0.0.tar.gz.

File metadata

  • Download URL: ofac_sdn_parser-1.0.0.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for ofac_sdn_parser-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f763970fc0953c13d33c2c8f384ab800f26d9964172d9faf02bf8036a0d7e4e9
MD5 13fbd47f575b9e08297e6b266e2f65be
BLAKE2b-256 56d0d4bd6d7575df0feb066e04682bc0a353b385aa6fad3a2b7156e61aa0dd63

See more details on using hashes here.

File details

Details for the file ofac_sdn_parser-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for ofac_sdn_parser-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a3921f3f282fc766124505ca663db203447b275ef5f44a2c65bf44c98a0c6ed
MD5 a8e6f9b49e7ad3c94033cf8c850a0211
BLAKE2b-256 3326349a018ba1d23a9560b420c8252e24d1ec89e56be3d75864433a2d0226fd

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page