API Documentation

Access sanctions data through our free, public API. No API key required.

Base URL

Base URL
https://www.ammitto.org/api/v1

Endpoints

GET/index.jsonld

Catalogue 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.

Example Request
curl https://www.ammitto.org/api/v1/index.jsonld
Example Response
{
  "@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", "..."]
    }
  ]
}
GET/stats.json

Entity and entry counts per source, and the totals. About 1 KB — read this rather than counting a larger file.

Example Request
curl https://www.ammitto.org/api/v1/stats.json
Example Response
{
  "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
}
GET/sources/{source}.jsonld

Every entity and entry from one source, as JSON-LD. Fourteen sources publish today; the catalogue lists them.

Example Request
curl https://www.ammitto.org/api/v1/sources/eu.jsonld
Example Response
{
  "@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 }
      ]
    }
  ]
}
GET/node/entity/{source}/{id}.jsonld

One entity on its own. Cheaper than the source aggregate when you already know the identifier; /node/entity/index.jsonld lists them.

Example Request
curl https://www.ammitto.org/api/v1/node/entity/au/100.jsonld
Example Response
{
  "@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 }
  ]
}
GET/all.jsonld and /all.ttl

The 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.

Example Request
curl -H 'Accept-Encoding: gzip' https://www.ammitto.org/api/v1/all.jsonld
Example Response
{
  "@context": "https://ammitto.org/api/v1/context.jsonld",
  "@graph": [ /* every entity, entry, regime, authority and instrument */ ]
}
GET/ontology/classes.jsonld

The published vocabulary: 18 classes, with properties.jsonld and hierarchy.json beside it. context.jsonld at the root maps the terms every document above uses.

Example Request
curl https://www.ammitto.org/api/v1/ontology/classes.jsonld
Example Response
{
  "@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"
    }
  ]
}
GET/facets/{facet}.json

Value lists for filtering — types, authorities, regimes, list types, countries, statuses — each with a count.

Example Request
curl https://www.ammitto.org/api/v1/facets/types.json
Example Response
{
  "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

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

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

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.