followthemoney defines a simple data model for storing complex object graphs. You will need to understand three concepts: entities, entity references and entity streams.


Entities are often expressed as snippets of JSON, with three standard fields: a unique id, a specification of the type of the entity, called schema, and a set of properties. All properties are multi-valued and the individual values are always strings.

    "id": "1b38214f88d139897bbd13eabde464043d84bbf9",
    "schema": "Person",
    "properties": {
        "name": ["John Doe"],
        "nationality": ["us", "au"],
        "birthDate": ["1982"]

The set of valid property names is defined by the Schemata definitions. For example, a Person has a nationality, while a Company allows for setting a jurisdiction. Both properties, however, have the same property type, Country.


One key function of entities is to reference other entities. This is achieved via a special property type, Entity. Properties of this type simply store the ID of another entity. For example, a Passport entity can be linked to a Person entity via its holder property:

    "id": "passport-entity-id",
    "schema": "Passport",
    "properties": {
        "holder": ["person-entity-id"],
        "number": ["CJ 7261817"]


Applications using followthemoney data usually need to resolve references bi-directionally. In the context of the example above, they will need to be able to access the person based on it’s ID in order to follow the holder link, but also query an inverted index to retrieve all the passports which reference a given person.

In Aleph this is achieved using ElasticSearch and exposed via the /api/2/entities/<id>/expand API endpoint.

Interstitial entities

Often, a link between two entities will have its own attributes. For example, an investigator looking at a person that owns a company might want to know not just when that interest was acquired, but also what percentage of shares the person holds.

This is addressed by making interstitial entities. In the example above, an Ownership entity would be created, with references to the person as its owner property and to the company as its asset property. That entity can then define further properties, including startDate and percentage:

    "id": "ownership-entity-id",
    "schema": "Ownership",
    "properties": {
        "owner": ["person-entity-id"],
        "asset": ["company-entity-id"],
        "startDate": ["2020-01-01"],
        "percentage": ["51%"],


It’s tempting to simplify this model by assuming that entities derived from Thing are node entities, and those derived from Interval are edges. This assumption is false and it will quickly lead to nasty bugs in your code.


Many tools in the followthemoney ecosystem use streams of entities to transfer or store information. Entity streams are simply sequences of entity objects that have been serialised to JSON as single lines without any indentation, each entity separated by a newline.

Entity streams are read and produced by virtually every part of the Command-line functions, the Aleph API, and they’re also supported by the ingestors. When stored to disk as a file, the extensions .ftm or .ijson should be used.