Deterministic sanctions & watchlist screening, built for AI agents.
OFACUNEUUK OFSIBIS Entity ListDenied PersonsCanada SEMAITAR~44k partiesdaily
Jump to: QuickstartPayment optionsEndpoints MatchingWatchesDiscovery
curl -X POST https://watchtower-api.com/v1/keys \
-H 'Content-Type: application/json' -d '{"note":"my-agent"}'
# → {"api_key":"ak_...","trial_credit_usd":0.05}
curl -X POST https://watchtower-api.com/v1/screen \
-H 'Authorization: Bearer ak_YOUR_KEY' -H 'Content-Type: application/json' \
-d '{"name":"Vladmir Putin"}'
# → {"match":true,"matches":[{"name":"PUTIN, Vladimir Vladimirovich",
# "score":0.97,"source":"OFAC-SDN","programs":["RUSSIA-EO14024"],
# "dob":["07 Oct 1952"],"nationality":["Russia"]}],
# "snapshot_version":"...","algorithm":"wt-match-2"}
curl -X POST https://watchtower-api.com/v1/screen/address \
-H 'Authorization: Bearer ak_YOUR_KEY' -H 'Content-Type: application/json' \
-d '{"address":"0x0330070FD38Ec3bB94F58FA55D40368271E9e54A"}'
Both screening endpoints speak the x402 protocol (v1 and v2). Call with no credentials, read the
402 challenge (PAYMENT-REQUIRED header for v2, JSON body for v1), and retry with a
signed payment. Any standard x402 client handles this automatically:
import { wrapFetchWithPayment, x402Client } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm';
const client = new x402Client().register('eip155:8453', new ExactEvmScheme(signer));
const pay = wrapFetchWithPayment(fetch, client);
const res = await pay('https://watchtower-api.com/v1/screen', {
method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({ name:'Wagner Group' })
}); // settlement receipt returned in the PAYMENT-RESPONSE header
Prepaid balance per key. New keys include free trial credit; top up with a Stripe credit pack via
POST /v1/topup (card top-ups activate once the operator's Stripe account is live).
Point any MCP client at https://watchtower-api.com/mcp (streamable HTTP). Tools: create_api_key,
screen_name, screen_names_batch, screen_crypto_address,
create_watch, list_watches, get_screening_info. Keys are passed as tool
arguments — no auth handshake.
| Method & path | Does | Price |
|---|---|---|
POST /v1/keys | Create API key + trial credit | free |
POST /v1/screen | Screen a name (sanctions + export-control) | $0.02 |
POST /v1/screen/batch | Up to 500 names in one call | $0.015/name |
POST /v1/screen/address | OFAC sanctioned-address check | $0.01 |
POST /v1/watch | Monitor a name; webhook on change | $0.01/day |
GET /v1/entity/:uid | Full record for a matched uid | free |
GET /v1/balance | Remaining credit | free |
GET /v1/lists | List versions, source hashes, freshness | free |
GET /openapi.json | Machine-readable spec | free |
wt-match-2"Vladmir Putin" finds
"PUTIN, Vladimir Vladimirovich".Inc, Company, Ltd…) are discounted, so
"Apple Inc" does not false-match unrelated companies.threshold (default 0.82) trades recall for precision; types filters
person / entity / vessel / aircraft.Prepay to watch a counterparty. When the daily list refresh changes that name's match set, we
POST your webhook a watch_changed event with added[] (full new records)
and removed[] (uids). Failed deliveries retry — you never silently miss a change.
curl -X POST https://watchtower-api.com/v1/watch \
-H 'Authorization: Bearer ak_YOUR_KEY' -H 'Content-Type: application/json' \
-d '{"name":"Acme Trading Co","webhook_url":"https://you.example/hook","days":30}'
/llms.txt · /openapi.json ·
/.well-known/x402.json ·
/.well-known/agent-card.json ·
/v1/lists · MCP at /mcp