API Documentation
Access sanctions data through our free, public API. No API key required.
Base URL
https://www.ammitto.org/api/v1Endpoints
/index.jsonldCatalogue of everything a run published: each file with its media type and byte size, each collection with its members. Start here rather than guessing a path.
curl https://www.ammitto.org/api/v1/index.jsonld{
"@context": "https://ammitto.org/api/v1/context.jsonld",
"@type": "Index",
"slice": "catalogue",
"generated": "2026-08-20T13:30:48Z",
"entries": [
{
"name": "all.jsonld",
"url": "all.jsonld",
"mediaType": "application/ld+json",
"description": "Every node in one graph",
"bytes": 155683385
},
{
"name": "sources",
"url": "sources",
"description": "One aggregate per source",
"members": ["au.jsonld", "ca.jsonld", "ch.jsonld", "..."]
}
]
}/stats.jsonEntity and entry counts per source, and the totals. About 1 KB — read this rather than counting a larger file.
curl https://www.ammitto.org/api/v1/stats.json{
"generated_at": "2026-08-20T13:30:48Z",
"sources": {
"eu": { "entities": 6329, "entries": 6329 },
"us": { "entities": 19207, "entries": 19207 },
"uk": { "entities": 6349, "entries": 6349 }
},
"total_entities": 61051,
"total_entries": 61051,
"total_regimes": 179
}/sources/{source}.jsonldEvery entity and entry from one source, as JSON-LD. Fourteen sources publish today; the catalogue lists them.
curl https://www.ammitto.org/api/v1/sources/eu.jsonld{
"@context": "https://ammitto.org/api/v1/context.jsonld",
"@graph": [
{
"@id": "https://www.ammitto.org/entity/eu/13",
"@type": "PersonEntity",
"entityType": "person",
"names": [
{ "@type": "NameVariant", "fullName": "…", "script": "Latn", "isPrimary": true }
]
}
]
}/node/entity/{source}/{id}.jsonldOne entity on its own. Cheaper than the source aggregate when you already know the identifier; /node/entity/index.jsonld lists them.
curl https://www.ammitto.org/api/v1/node/entity/au/100.jsonld{
"@id": "https://www.ammitto.org/entity/au/100",
"@type": "PersonEntity",
"entityType": "person",
"names": [
{ "@type": "NameVariant", "fullName": "Nazir Mohammad Abdul Basir", "script": "Latn", "isPrimary": true },
{ "@type": "NameVariant", "fullName": "Nazar Mohammad", "script": "Latn", "isPrimary": false }
]
}/all.jsonld and /all.ttlThe whole graph in one file — JSON-LD or RDF/Turtle. Large: 155 MB and 115 MB respectively, though the JSON-LD transfers at about 8 MB gzipped. Prefer a source aggregate or a node document unless you genuinely want everything.
curl -H 'Accept-Encoding: gzip' https://www.ammitto.org/api/v1/all.jsonld{
"@context": "https://ammitto.org/api/v1/context.jsonld",
"@graph": [ /* every entity, entry, regime, authority and instrument */ ]
}/ontology/classes.jsonldThe published vocabulary: 18 classes, with properties.jsonld and hierarchy.json beside it. context.jsonld at the root maps the terms every document above uses.
curl https://www.ammitto.org/api/v1/ontology/classes.jsonld{
"@context": "https://ammitto.org/api/v1/context.jsonld",
"@graph": [
{
"@id": "https://www.ammitto.org/ontology/Entity",
"@type": "rdfs:Class",
"label": "Entity",
"comment": "Base class for all sanctionable entities"
}
]
}/facets/{facet}.jsonValue lists for filtering — types, authorities, regimes, list types, countries, statuses — each with a count.
curl https://www.ammitto.org/api/v1/facets/types.json{
"facets": [
{ "code": "person", "name": "Person", "icon": "user", "count": 31239 },
{ "code": "organization", "name": "Organization", "icon": "building", "count": 26819 },
{ "code": "vessel", "name": "Vessel", "icon": "ship", "count": 2651 }
]
}Code Examples
JavaScript
// Ask the catalogue what exists before fetching anything
const index = await (await fetch('https://www.ammitto.org/api/v1/index.jsonld')).json();
for (const entry of index.entries) {
console.log(entry.name, entry.bytes ?? `${entry.members?.length ?? 0} members`);
}
// Then take one source
const data = await (await fetch('https://www.ammitto.org/api/v1/sources/eu.jsonld')).json();
// The graph holds entity AND sanction-entry nodes; entries carry no names
for (const node of data['@graph']) {
if (!node['@id'].includes('/entity/')) continue;
console.log(node.names?.[0]?.fullName);
}Ruby
require 'net/http'
require 'json'
stats = JSON.parse(Net::HTTP.get(URI('https://www.ammitto.org/api/v1/stats.json')))
# The totals are top-level keys, not nested under "totals"
puts "Entities: #{stats['total_entities']} across #{stats['sources'].size} sources"
stats['sources'].each { |code, c| puts " #{code}: #{c['entities']}" }Python
import requests
BASE = 'https://www.ammitto.org/api/v1'
# One entity, by identifier — far cheaper than the source aggregate
node = requests.get(f'{BASE}/node/entity/au/100.jsonld').json()
print(node['@type'], node['names'][0]['fullName'])
# Or a whole source
data = requests.get(f'{BASE}/sources/eu.jsonld').json()
for n in data['@graph']:
if '/entity/' not in n['@id']:
continue
for name in n.get('names', [])[:1]:
if name.get('fullName'):
print(name['fullName'])Rate Limits
There are no strict rate limits, but please be respectful of the service. For high-volume access, consider downloading the data files and hosting them locally.