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.

Metadata

Release files for ofac-sdn-parser 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ofac-sdn-parser 1.0.0
File Size Uploaded
ofac_sdn_parser-1.0.0.tar.gz 11.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ofac-sdn-parser 1.0.0
File Interpreter ABI Platform
ofac_sdn_parser-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.7 kB

Release files / ofac_sdn_parser-1.0.0.tar.gz

Download URL ofac_sdn_parser-1.0.0.tar.gz
Size 11.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f763970fc0953c13d33c2c8f384ab800f26d9964172d9faf02bf8036a0d7e4e9
BLAKE2b-256 checksum
How to use checksums
56d0d4bd6d7575df0feb066e04682bc0a353b385aa6fad3a2b7156e61aa0dd63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / ofac_sdn_parser-1.0.0-py3-none-any.whl

Download URL ofac_sdn_parser-1.0.0-py3-none-any.whl
Size 10.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a3921f3f282fc766124505ca663db203447b275ef5f44a2c65bf44c98a0c6ed
BLAKE2b-256 checksum
How to use checksums
3326349a018ba1d23a9560b420c8252e24d1ec89e56be3d75864433a2d0226fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release 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