Sanctions Screening API
One endpoint, four official lists
Bring 28,492 sanctions and export-control entries from US OFAC, the UN, the EU and China MOFCOM into your own ERP, risk or KYC systems. Send a name; get back whether it matched, which entries it matched, and a link to the official record you can open and verify.
Who it is for
- Traders and freight forwarders: screen counterparties automatically before ordering, booking or releasing cargo — a hit blocks the flow instead of relying on someone remembering.
- Banks and trade finance: add a screening step to credit approval and keep traceable due-diligence evidence.
- Law firms and compliance advisers: re-screen an existing client book in bulk and export CSV straight into the report annex.
- SaaS vendors and integrators: add a compliance module to your own product without maintaining list crawlers.
Why not build it yourself
Four sources, four formats: OFAC ships CSV, the UN ships XML, the EU has its own database, and China MOFCOM has no API at all — only announcement web pages.
And the lists move daily — our last OFAC refresh came back 97 entries lighter (delistings must be synced too, or you produce false positives).
That maintenance cost is ongoing, not one-off.
Three steps to integrate
1. Subscribe to the API plan and create a key
The API requires the API plan (US$19.9/mo, includes everything in membership).
Sign in, open the Membership tab to subscribe, then create a key under API keys. Keys look like tp_xxxxxxxx.
The plaintext key is shown only once, at creation — put it into your secret manager right away.
2. Send a request
curl -H "Authorization: Bearer tp_YOUR_KEY" "https://tradeprotected.com/api/v1/screen?name=GAZPROM"
3. Read the response
{
"matched": true,
"count": 2,
"rows": [
{
"source": "OFAC",
"name": "GAZPROM NEFT",
"type": "entity",
"programs": "RUSSIA-EO14024",
"listed_on": "2022-02-24",
"url": "https://sanctionssearch.ofac.treas.gov/..."
}
]
}
matched is a boolean you can branch on directly; rows[].url points at the official record — file it as your verification evidence.
Endpoints
Screen a single name. Parameter name (required, max 200 characters). A 7-digit number is treated as a vessel IMO and matched exactly.
Batch screening, up to 100 names per call. Handy for checking buyer, seller, shipowner and consignee in one go before an order.
Browse or bulk-pull the lists, for keeping your own copy in sync. Parameters: q keyword, source, type, limit (default 100, max 500), offset.
Entry counts and last-updated time per source. A sync job can check this first and skip a full pull when nothing changed.
Parameters
name | Name to screen, or a 7-digit IMO. Required for GET /screen |
|---|---|
names | Array of names for batch screening, in the POST body, max 100 |
source | OFAC / UN / EU / EUX / CN; empty means all |
type | entity / individual / vessel / aircraft |
format | json (default) / xlsx (Excel) / csv / ndjson |
limit | Rows per page, default 100, max 500 |
offset | Offset, used with limit for paging |
Three ways to use it
Same data, three ways to consume it, ordered by how much code you have to write:
- Embedded widget — paste an iframe into your own site and visitors search directly. No code.
- Parameterised calls — send an HTTP request, get JSON back, for your programs.
- Spreadsheet export — add one format parameter and download Excel / CSV.
Option 1: embed it in your own site
Paste the snippet below into any page of your corporate site and a sanctions search box appears, backed by our database and plain enough to blend into your layout. A good fit for forwarders, law firms and associations offering clients a self-service check.
<iframe src="https://tradeprotected.com/embed?key=tp_YOUR_KEY&lang=en"
style="width:100%;height:420px;border:1px solid #e4eaf1;border-radius:12px"
loading="lazy"></iframe>
Lock it to your domain
A key inside embed code is publicly visible — anyone viewing your page source can read it. So set the allowed domains for that key under Membership → API keys (e.g. yourcompany.com); even if the key is copied, it will not work on another site. This is the same approach front-end keys like Google Maps use.
We recommend separate keys for embedding and for server-side calls: lock the embed key to your domain, and keep the server key unlocked but only on your server. One account can hold five keys at a time, which is enough to split by environment.
Option 3: export to a spreadsheet
Add the format parameter — every query endpoint supports it.
- Excel —
?format=xlsx. A real .xlsx file with bilingual headers, tuned column widths and a bold dark header row: double-click and it goes straight into the report annex, no reformatting. - CSV —
?format=csv. Includes a UTF-8 BOM so Excel opens non-Latin text correctly; convenient for scripts. - NDJSON —
?format=ndjson. One independent JSON object per line, suited to streaming pipelines — a full pull never has to be held in memory at once. - JSON (default) — includes
matchedandcountsummary fields for programmatic decisions.
# export the China MOFCOM list to Excel
curl -H "Authorization: Bearer tp_YOUR_KEY" "https://tradeprotected.com/api/v1/sanctions?source=CN&limit=500&format=xlsx" -o cn-list.xlsx
# save a single screening result as a spreadsheet for your audit file
curl -H "Authorization: Bearer tp_YOUR_KEY" "https://tradeprotected.com/api/v1/screen?name=GAZPROM&format=xlsx" -o gazprom.xlsx
# look up a vessel by IMO
curl -H "Authorization: Bearer tp_YOUR_KEY" "https://tradeprotected.com/api/v1/screen?name=9209508"
Code samples
Python
import requests
KEY = "tp_YOUR_KEY"
r = requests.get(
"https://tradeprotected.com/api/v1/screen",
params={"name": "GAZPROM"},
headers={"Authorization": "Bearer " + KEY},
timeout=20,
)
r.raise_for_status()
data = r.json()
if data["matched"]:
print("MATCH", data["count"], "hit(s) — needs manual review")
for row in data["rows"]:
print(row["source"], row["name"], row["url"])
Node.js
const KEY = process.env.TP_API_KEY;
async function screen(name) {
const url = new URL("https://tradeprotected.com/api/v1/screen");
url.searchParams.set("name", name);
const r = await fetch(url, { headers: { authorization: "Bearer " + KEY } });
if (!r.ok) throw new Error("screen failed: " + r.status);
return r.json();
}
const out = await screen("SOVCOMFLOT");
console.log(out.matched ? "MATCH " + out.count : "clear");
Batch (Python)
names = ["GAZPROM", "ACSL", "SOVCOMFLOT"]
r = requests.post(
"https://tradeprotected.com/api/v1/screen",
json={"names": names},
headers={"Authorization": "Bearer " + KEY},
timeout=60,
)
for item in r.json()["results"]:
flag = "MATCH" if item["matched"] else "clear"
print(flag, item["query"], item["count"])
Quota and error codes
1000 calls per key per day, resetting at 00:00 UTC. Every response carries these two headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
An account can hold up to five active keys. Splitting them by environment (production / staging / a specific colleague) means you can revoke one without disturbing the other callers.
Errors
Errors always return {"error":{"code":"...","message":"..."}}. Branch on code, not on the message text.
| 401 | missing_key no key supplied · invalid_key key invalid or revoked |
|---|---|
| 403 | membership_required not subscribed or expired — keys stop working the moment the plan lapses and resume on renewal, no need to reissue |
| 429 | quota_exceeded daily allowance used up |
| 400 | missing_name / name_too_long / too_many_names parameter problems |
Important
Matching is normalised substring and phrase matching, so a hit is a due-diligence signal, not a legal conclusion. Namesakes and transliteration differences can produce false positives and false negatives; make the final call against the official record at url.
The API plan includes everything in membership, plus the data API, the embeddable widget and Excel export.
Comparable screening APIs are typically annual contracts starting in the thousands of dollars. Ours is monthly and cancellable any time. Run a few queries free and judge the data before committing.