FollowTheMoney JSON
Our JSON files follow the FollowTheMoney entity layout: each entity has an id, a schema and a set of properties whose values are always lists of strings. They are written as JSON lines (one complete JSON object per line), so they can be streamed without loading the whole file.
Two files
entities.ftm.jsonholds every record as an entity, followed on the next line by itsSanctionentity: the listing on the source register. There are two lines per record. Use it to load a graph or an entity store, where the listing is a separate node.targets.nested.jsonholds one line per record, with its listing nested underproperties.sanctions. Use it when you want one self-contained object per listed party.
Both are UTF-8. See also the model reference, entity structure and flat and nested entities.
Entity fields
- id
- Record id,
crown-<number>. One record is one row from one source register. The listing has the idcrown-<number>-sanction. In the API, the same record is the number alone. - caption
- Display name.
- schema
Person,Company,Organization,Vessel,Airplane,LegalEntity(type not stated by the source) orSanction.- properties
- Property name to a list of string values. Absent properties are left out.
- referents
- Other ids merged into this one. Always an empty list today; merges are expressed with
canonical_id. - datasets
- Source register as a short identifier, e.g.
ofac_sdn,uk_ofsi,paris_mou_banned. - first_seen
- When we first collected the record (ISO 8601, UTC offset included).
- last_seen
- When the record was last confirmed at its source.
- last_change
- When the record last changed. Today this equals
last_seen. - target
trueon listed parties. Not present onSanctionentities.- canonical_id
- Present when we have matched the record with records from other registers as the same party:
crown-e-<merge id>. Group on it to see one party across registers.
Properties
| Property | On | Contents |
|---|---|---|
name | all records | Primary name as published |
alias | all records | Other names and spellings |
topics | all records | One of sanction, role.pep, debarment, reg.action |
birthDate | Person | YYYY, YYYY-MM or YYYY-MM-DD, to the precision published |
nationality | Person | ISO 3166-1 alpha-2, lower case |
country | other records | ISO 3166-1 alpha-2, lower case |
imoNumber | Vessel and others | IMO followed by seven digits |
sourceUrl | records, Sanction | Link to the record or list at the publisher |
notes | all records | Other published details as text (addresses, identifiers, flags, remarks) |
entity | Sanction | id of the listed record |
authority | Sanction | Source register name |
program | Sanction | Programme or listing basis, in the publisher's words |
listingDate | Sanction | Publication or listing date, where the register gives one |
sanctions | nested file only | The record's Sanction entities |
How complete each property is
| Property | Records with it | Share |
|---|---|---|
| Loading… | ||
Example: entities.ftm.json
Two lines from the maritime collection: a vessel and its listing (line breaks added for reading; each object is one line in the file).
{"id":"crown-380054154","caption":"PELIKAN","schema":"Vessel",
"properties":{"name":["PELIKAN"],"topics":["debarment"],"alias":["BALTIC ATLANT SHPG-LITHUANIA"],
"imoNumber":["IMO6922169"],"notes":["IMO 6922169 · Flag: Comoros · From: 09/12/2009 · ISM: BALTIC ATLANT SHPG-LITHUANIA"]},
"referents":[],"datasets":["paris_mou_banned"],"first_seen":"2026-09-24T11:38:49.104591+00:00",
"last_seen":"2026-09-24T11:38:49.104591+00:00","last_change":"2026-09-24T11:38:49.104591+00:00","target":true}
{"id":"crown-380054154-sanction","schema":"Sanction","caption":"Banned from Paris MoU ports — Multiple detentions",
"properties":{"entity":["crown-380054154"],"authority":["Paris MoU Banned"],
"program":["Banned from Paris MoU ports — Multiple detentions"]},
"datasets":["paris_mou_banned"],"first_seen":"2026-09-24T11:38:49.104591+00:00",
"last_seen":"2026-09-24T11:38:49.104591+00:00","last_change":"2026-09-24T11:38:49.104591+00:00"}
Example: targets.nested.json
The same record in the nested file: one line, with the listing inside properties.sanctions.
{"id":"crown-380054154","caption":"PELIKAN","schema":"Vessel",
"properties":{"name":["PELIKAN"],"topics":["debarment"],"alias":["BALTIC ATLANT SHPG-LITHUANIA"],
"imoNumber":["IMO6922169"],"notes":["…"],
"sanctions":[{"id":"crown-380054154-sanction","schema":"Sanction",
"caption":"Banned from Paris MoU ports — Multiple detentions",
"properties":{"entity":["crown-380054154"],"authority":["Paris MoU Banned"],
"program":["Banned from Paris MoU ports — Multiple detentions"]},
"datasets":["paris_mou_banned"], "first_seen":"…","last_seen":"…","last_change":"…"}]},
"referents":[],"datasets":["paris_mou_banned"],"first_seen":"…","last_seen":"…","last_change":"…","target":true}
Reading the files
Read one line at a time; the larger collections run to gigabytes (default: —).
import json
with open("targets.nested.json", encoding="utf-8") as f:
for line in f:
e = json.loads(line)
names = e["properties"].get("name", []) + e["properties"].get("alias", [])
programmes = [p for s in e["properties"].get("sanctions", [])
for p in s["properties"].get("program", [])]
print(e["id"], e["schema"], names[0], programmes)
# group records that we have matched as the same party
jq -r 'select(.canonical_id) | [.canonical_id, .id, .caption] | @tsv' targets.nested.json | sort
What the files do not hold yet
- Addresses, identity documents, ownership, family and associate links, positions held and crypto-wallet addresses are not separate entities or properties. Where a publisher gives them, they survive only as text in
notes. referentsis always empty; merges appear only throughcanonical_id.last_changeis the last confirmation date, not a true change date.- Entity types are inferred where the source does not give one, and some are wrong; see methodology.
Last updated 2026-10-03