# API Walk-Through

# Introduction

This page contains a walkthrough of Sayari's API. The walkthrough assumes that your API access token is stored under the TOKEN environment variable. If you don't have a token, follow these steps to obtain your token and run export TOKEN={api_token}.

The walkthrough also pipes JSON output through python -m json.tool for pretty-printing. If you don't have Python installed feel free to remove this step.

You will generally start a workflow by searching for an entity or record of interest. For example, if you're interested in Victoria Beckham, you might run:

curl "https://api.sayari.com/v1/search/entity?q=victoria+beckham&limit=1" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

This returns the top entity hit for the search term victoria beckham:

{
    "offset": 0,
    "limit": 1,
    "next": true,
    "size": {
        "count": 8,
        "qualifier": "eq"
    },
    "data": [
        {
            "id": "XabunnGRTK2ieyLtP-PiUQ",
            "label": "VICTORIA CAROLINE BECKHAM",
            "type": "person",
            "entity_url": "/entity/XabunnGRTK2ieyLtP-PiUQ",
            "identifiers": [
                {
                    "type": "uk_person_number",
                    "value": "055967030010"
                }
            ],
            "countries": [
                "GBR"
            ],
            "source_count": {
                "4ea8bac1bed868e1510ffd21842e9551": {
                    "count": 2,
                    "label": "UK Persons with Significant Control",
                },
                "ecdfb3f2ecc8c3797e77d5795a8066ef": {
                    "count": 14,
                    "label": "UK Companies House",
                }
            },
            "relationship_count": {
                "linked_to": 2,
                "shareholder_of": 2,
                "secretary_of": 1,
                "director_of": 10
            },
            "matches": {
                "name": [
                    "<em>VICTORIA</em> CAROLINE <em>BECKHAM</em>"
                ]
            }
        },
        ...
    ]
}

Here's an explanation of the important pieces of this result:

Field Path Value Description
data [...] An array of search hits
data[].id "5da6ee9e71914..." Sayari's unique ID for this entity token.
data[].label "VICTORIA CAROLINE BECKHAM" Sayari's label (usually a name) for this entity exist.
data[].type "person" The type of entity. See the ontology for all types.
data[].entity_url "/entity/5da6ee9e71914..." Relative URL to see more information on the entity
data[].identifiers [ { "type": "uk_person_number", "value": "055967030010"} ] A list of unique identifiers for the entity.
data[].countries ["GBR"] A list of associated countries for the entity as ISO 3166-1 alpha-3 (opens new window) codes.
data[].source_count [...] Gives a count of unique documents that this entity was found in, per source
data[].relationship_count {"linked_to": 2, "shareholder_of": 2, ... } Counts the number of distinct neighbor entities by relationship type
data[].matches {"name": ["<em>VICTORIA</em> CAROLINE <em>BECKHAM</em>"] } Hit highlighting

The primary purpose of these fields is to decide if a search hit is worthy of further investigation. For example, the data[].identifiers and data[].countries fields might help determine whether this is the correct Victoria Beckham. The data[].relationship_count fields give an idea of how many entities you might discover if you investigate further. For any relevant looking search results, request that full entity via the Entity endpoint.

# Entity Search Facets

To view faceted counts of search results per country, source, and entity type, add the facet query parameter to your search. This can be useful to understand the distribution of search results. For example, to add facets to the above query for Victoria Beckham:

curl "https://api.sayari.com/v1/search/entity?q=victoria+beckham&facets=true" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

In addition to the standard search results fields discussed above, the response will include a facets property:

{
    "offset": 0,
    "limit": 100,
    "next": false,
    "size": {
        "count": 8,
        "qualifier": "eq"
    },
    "data": [...],
    "facets": {
        "sources": [
            {
                "key": "ecdfb3f2ecc8c3797e77d5795a8066ef",
                "doc_count": 6
            },
            {
                "key": "4ea8bac1bed868e1510ffd21842e9551",
                "doc_count": 4
            },
            {
                "key": "ecdfb3f2ecc8c3797e77d5795a8066ef",
                "doc_count": 3
            },
            {
                "key": "03c98191ef91d7fbd9a29b3d5b862249",
                "doc_count": 1
            },
            {
                "key": "2a4fe9a14e332c8f9ded1f8a457c2b89",
                "doc_count": 1
            }
        ],
        "countries": [
            {
                "key": "GBR",
                "doc_count": 7
            },
            {
                "key": "CAN",
                "doc_count": 1
            }
        ],
        "type": [
            {
                "key": "company",
                "doc_count": 4
            },
            {
                "key": "person",
                "doc_count": 4
            }
        ]
    }
}

The above reveals that, in addition to returning hits in the UK, we also see a hit in Canada, and that results are split between people and countries. If some of these sources, countries, or types are of particular interest, for instance if we are only interested in looking at people, not companies, named Victoria Beckham, use search filters, described below.

# Entity Search Filters

To further filter search results by source, country, or entity type, use search filters.

For example, a search for the common name Jane Smith returns many results. If you are confident that the Jane Smith you are interested in has connections to Hong Kong, you can run the following search filtered by country:

curl "https://api.sayari.com/v1/search/entity?q=jane+smith&filters=country=HKG" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

Sayari uses ISO 3166 Trigram (opens new window) country codes to identify countries.

Alternatively, if you are interested in someone from the "China SAIC" source, run the following search filtered by source:

curl "https://api.sayari.com/v1/search/entity?q=jane+smith&filters=source=fcfa3d1c6b5f9744188fc01d0999fb76" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

To get a list of sources by id, use the sources endpoint: https://api.sayari.com/v1/sources.

Lastly, to filter on an entity type, e.g. person or company, use filters=entity_type=$VALUE search parameter. See the ontology for all types. For example, to get all properties that mention Halland in the UK Land Overseas Company Ownership Data (OCOD), run the following query:

curl "https://api.sayari.com/v1/search/entity?q=halland&filters=entity_type=property" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

# Entity Search Fields

In addition to filtering by country, source, and entity type, Sayari search supports searching by the fields identifier, address, name, position, and contact. For example, to search for entities with an identifier that matches 76543, run:

curl "https://api.sayari.com/v1/search/entity?q=76543&fields=identifier" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

For a detailed explanation of all of the above search functionality, read the search API reference.

In addition to obtaining records by examining the /entity/ response, you can search for records directly. This is useful when we have a record indexed as plain text, which is common when the source document is a PDF.

Searching records is also useful when you want to search for multiple entities occurring in the same record. For example to find records that mention both Victoria Beckham and David Beckham, you can use the search term: "DAVID ROBERT JOSEPH BECKHAM" "VICTORIA CAROLINE BECKHAM"

curl "https://api.sayari.com/v1/search/record?q=\"DAVID+ROBERT+JOSEPH+BECKHAM\"+\"VICTORIA+CAROLINE+BECKHAM\"&limit=1" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

This gives the top result:

{
    "offset": 0,
    "limit": 1,
    "next": true,
    "size": {
        "count": 6,
        "qualifier": "eq"
    },
    "data": [
        {
            "id": "ecdfb3f2ecc8c3797e77d5795a8066ef%2F03190273%2F1540252800000",
            "label": "UK Companies House - 10/23/2018",
            "source": "ecdfb3f2ecc8c3797e77d5795a8066ef",
            "publication_date": "2018-10-23",
            "acquisition_date": "2018-10-23",
            "references_count": 3,
            "record_url": "/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03190273%2F1540252800000",
            "matches": {
                "name": [
                    "<em>VICTORIA CAROLINE BECKHAM</em>",
                    "<em>DAVID ROBERT JOSEPH BECKHAM</em>"
                ]
            }
        }
    ]
}

Here's an explanation of the important pieces of this result:

Field Path Value Description
data [...] An array of search record hits
data[].id "ecdfb3f2ecc8c3797e7..." Sayari's unique ID for this record
data[].label "UK Companies House - 10/23/2018" Sayari's record label
data[].source "ecdfb3f2ecc8c3797e77d5795a8066ef" The record source id
data[].publication_date 2018-10-23 The date the record was published. Potentially undefined
data[].acquisition_date 2018-10-23 The date Sayari acquired the record
data[].record_url "/record/ecdfb3f2ecc..." Relative URL to see more information on the record
data[].matches {"name": ["<em>VICTORIA ...] } Hit highlighting

We can use the /record/ endpoint to get more information about this record:

curl "https://api.sayari.com/v1/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03190273%2F1540252800000" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

Here's a slim version of the response:

{
    "id": "ecdfb3f2ecc8c3797e77d5795a8066ef%2F03190273%2F1540252800000",
    "label": "UK Companies House - 10/23/2018",
    "source": "ecdfb3f2ecc8c3797e77d5795a8066ef",
    "publication_date": "2018-10-23",
    "acquisition_date": "2018-10-23",
    "references_count": 3,
    "record_url": "/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03190273%2F1540252800000",
    "references": {
        "data": [
            {
                "entity": {
                    "id": "c116402ca8c783c1fb3a1857ba4e9e29758e3ddf73aecf40031285e1",
                    "label": "FOOTWORK PRODUCTIONS LIMITED",
                    "type": "company",
                    ...
                },
                "type": "about"
            },
            {
                "entity": {
                    "id": "41a5cbf54c04685d9bd27051ed79ffc89e183046b682011954066ee9",
                    "label": "DAVID ROBERT JOSEPH BECKHAM",
                    "type": "person",
                    ...
                   }
                "type": "mentions"
            },
            {
                "entity": {
                    "id": "XabunnGRTK2ieyLtP-PiUQ",
                    "label": "VICTORIA CAROLINE BECKHAM",
                    "type": "person",
                   },
                   ...
                "type": "mentions"
            }
        ]
    }
}

With this response we can see that the record in question mentions VICTORIA CAROLINE BECKHAM and DAVID ROBERT JOSEPH BECKHAM and is about FOOTWORK PRODUCTIONS LIMITED.

# Get Entity

curl "https://api.sayari.com/v1/entity/XabunnGRTK2ieyLtP-PiUQ" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

The response is quite large, so we'll go through piece by piece, and only show a subset of values. Here's a list of top level fields:

{
    "id": "XabunnGRTK2ieyLtP-PiUQ",
    "label": "VICTORIA CAROLINE BECKHAM",
    "type": "...",
    "entity_url": "...",
    "identifiers": [...],
    "countries": [...],
    "source_count": {...},
    "relationship_count": {...},
    "attributes": {...},
    "relationships": {...},
    "possibly_same_as": {...},
    "referenced_by": {...}
}

The first several fields (id through relationship_count) are the same as the ones returned for each search result, shown above.

Here's an overview of the rest of the fields:

Field Path Value Description
attributes {..., "data": [...]} Identifying information and miscellaneous characteristics of this entity hits
relationships {..., "data": [...]} Information about relationships to other entities
referenced_by {..., "data": [...]} Information about the records that mention this entity
possibly_same_as {..., "data": [...]} Information other entities that are possibly the same as this entity

Let's go through these new fields one by one.

# Attributes

The attributes field contains important information about the entity like aliases, addresses, and other miscellaneous information. Here's the general shape for this entity:

  ...
  "attributes": {
    "country": { ... , "data": [...]},
    "identifier": { ... , "data": [...]},
    "address": { ... , "data": [...]},
    "date_of_birth": { ... , "data": [...]},
    "additional_information": { ... , "data": [...]},
    "name": { ... , "data": [...]}
  },
  ...

You can see a list of all possible attributes in the ontology.

An entity can have zero or more instances of each attribute type. Each attribute type is therefore stored as an array of value-objects, which can be paged individually.

# Address

Let's take a look at the address attribute as an example:

"attributes": {
  "address": {
    "next": "b9dc2ca839c31",
    "prev": "49dc2ca839c31",
    "limit": 100,
    "size": {
        "count": 6,
        "qualifier": "eq"
    },
    "data": [
        {
            "properties": {
                "value": "DELOITTE & TOUCHE, PO BOX 506 180 STRAND, WC2R 1ZP",
                "house": "Deloitte & Touche",
                "house_number": "180",
                "po_box": "Po Box 506",
                "road": "Strand Wc2r 1zp",
                "postcode": "WC2R 1ZP"
            },
            "record": [
                "ecdfb3f2ecc8c3797e77d5795a8066ef/03333365/1540252800000"
            ],
            "record_count": 4
        },
        {
            "properties": {
                "value": "5TH FLOOR 89 NEW BOND STREET, W1S 1DA",
                "house_number": "89",
                "level": "5th Floor",
                "road": "New Bond Street W1s",
                "postcode": "1da"
            },
            "record": [
                "ecdfb3f2ecc8c3797e77d5795a8066ef/03190273/1540252800000"
            ],
            "record_count": 4
        },
        {
            "properties": {
                "value": "FIFTH FLOOR 89 NEW BOND STREET, W1S 1DA",
                "house_number": "89",
                "level": "Fifth Floor",
                "road": "New Bond Street W1s",
                "postcode": "1da"
            },
            "record": [
                "ecdfb3f2ecc8c3797e77d5795a8066ef/03198152/1540252800000"
            ],
            "record_count": 3
        },
        ...
    ]
  }
}

Here's a list of generic attribute fields that are present for all attributes (not just address):

Field Path Value Description
attributes.address.next string Pagination token to return the next page
attributes.address.prev string Pagination token to return the previous page
attributes.address.limit int Max number of attributes to return
attributes.address.size { "count": int, ...} Total number of attributes of this type
attributes.address.data[].record ["...", ...] Link to one or more sourcing records for this attribute
attributes.address.data[].record_count int Total number of distinct sourcing records for this attribute
attributes.address.data[].properties {...} Attribute fields. The exact fields vary per attribute (see here)

The first four fields give information about pagination. The next two give information about sourcing. Finally, properties gives the actual attribute.

In the case of the address attribute, the properties give us the complete address as a string under value and then breaks down that address into constituent parts with the remaining fields.

Attributes are returned sorted by record_count in descending order, so the most commonly cited attributes are returned first. There is sometimes duplication in returned attributes. For example the second and third addresses returned are the same, with only a minor variation. Work is ongoing to deduplicate such cases.

# Additional Information

Another important attribute to understand is additional_information. This attribute is used to store information that's important, but doesn't fit into a better defined attribute. In this case, we get the following additional_information:

"attributes": {
  "additional_information": {
    "next": "b9dc2ca839c31",
    "prev": "49dc2ca839c31",
    "limit": 100,
    "size": {
        "count": 3,
        "qualifier": "eq"
    },
    "data": [
        {
            "properties": {
                "value": "FASHION DESIGNER",
                "type": "Occupation"
            },
            "record": [
                "ecdfb3f2ecc8c3797e77d5795a8066ef/03407448/1540252800000"
            ],
            "record_count": 7
        },
        {
            "properties": {
                "value": "MUSICIAN",
                "type": "Occupation"
            },
            "record": [
                "ecdfb3f2ecc8c3797e77d5795a8066ef/03198152/1540252800000"
            ],
            "record_count": 6
        }
    ]
  }
}

Here the type property gives us a key, and the value property gives us the value. So in this case, we can see that we have two reported Occupation values for Victoria Beckham: MUSICIAN and FASHION DESIGNER.

# Extra fields

In some cases we include "extra" fields under an attribute's properties. These fields are not part of the attribute's standard fields (shown here). Extra fields are used when we get some useful information from the source that doesn't fit into the schema. For example a name attribute with an extra field might look like this:

{
    "properties": {
        "value": "VICTORIA CAROLINE BECKHAM",
        "context": "primary",
        "Maiden Name": "false"
    },
    "record": [
        "ecdfb3f2ecc8c3797e77d5795a8066ef/03190273/1540252800000"
    ],
    "record_count": 16
}

In the above name, the Maiden Name field is an extra field. It's not part of the schema, but might still have analytic value.

# Relationships

The relationships field lists relationships for the entity in question. This allows us to connect Victoria Beckham with other known entities.

Here's an outline:

"relationships": {
  "director_of": {
    "next": "b9dc2ca839c31",
    "prev": "49dc2ca839c31",
    "limit": 100,
    "size": {
        "count": 3,
        "qualifier": "eq"
    },
    "data": [
      {
        "target": { ... },
        "types": { ... }
      },
      ...
    ]
  }
}

Relationships are aggregated at several levels. First, relationships are aggregated by type (in this case director_of). All director_of relationships will be found under relationships.director_of.data.

Next, relationships are aggregated by target entity. This means that an adjacent entity will appear only once per relationship type.

The relationships.director_of.data array is pageable like other arrays. It contains a list of objects, each with a target object which describes the related entity and a types object that describes the relationship itself. For example, here's a single director_of relationship for Victoria Beckham:

{
    "target": {
        "id": "XabunnGRTK2ieyLtP-PiUQ",
        "label": "OCTOPUS DIRECT LIMITED",
        "type": "company",
        "entity_url": "/v1/entity/XabunnGRTK2ieyLtP-PiUQ",
        "identifiers": [
            {
                "type": "uk_company_number",
                "value": "03198152"
            }
        ],
        "countries": [
            "GBR"
        ],
        "source_count": {
            "ecdfb3f2ecc8c3797e77d5795a8066ef": {
                "count": 1,
                "label": "UK Companies House",
            }
        },
        "relationship_count": {
            "has_director": 5
        }
    },
    "types": {
        "director_of": [
            {
                "record": "ecdfb3f2ecc8c3797e77d5795a8066ef/03198152/1540252800000",
                "attributes": {
                    "position": [
                        {
                            "value": "Current Director"
                        }
                    ]
                },
                "fromDate": "1997-11-22"
            }
        ]
    },
    "record_count": 1
}

The target section gives us similar information to an entity search result. It summarizes information about the other entity (OCTOPUS DIRECT LIMITED) and helps determine whether it is worthy of further attention.

The types section gives us information about the relationship between Victoria Beckham and OCTOPUS DIRECT LIMITED. This is done by providing attributes, similar to the entity attribute discussed above. It also includes date information for the relationship when available.

For example in this case the director_of relationship started on November 22, 1997 and Victoria Beckham's position according to the source record is "Current Director."

If we were interested in obtaining detailed information on the related entity OCTOPUS DIRECT LIMITED we could run the following:

curl "https://api.sayari.com/v1/entity/XabunnGRTK2ieyLtP-PiUQ" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

Using the provided URL at target.entity_url.

# Possibly Same As

The possibly_same_as.data array gives us a list of other entities that are likely the same as Victoria Beckham. These other entities did not meet the threshold required to merge two entities into a single entity, but they are likely the same person, so we provide a link. One item from this array is shown below:

{
    "entity": {
        "id": "bSpwCtNMbwtrWARRyo6jGg",
        "label": "VICTORIA CAROLINE BECKHAM",
        "type": "person",
        "entity_url": "/v1/entity/bSpwCtNMbwtrWARRyo6jGg",
        "identifiers": [
            {
                "type": "uk_person_number",
                "value": "239702000001"
            }
        ],
        "countries": [
            "GBR"
        ],
        "source_count": {
            "ecdfb3f2ecc8c3797e77d5795a8066ef": {
                "count": 1,
                "label": "UK Companies House"
            }
        },
        "relationship_count": {
            "director_of": 1
        }
    },
    "matches": {
        "name": [
            {
                "value": "BECKHAM CAROLINE VICTORIA",
                "source": "VICTORIA CAROLINE BECKHAM",
                "target": "VICTORIA CAROLINE BECKHAM"
            }
        ],
        "date_of_birth": [
            {
                "value": "1974-04-??",
                "source": "1974-04",
                "target": "1974-04"
            }
        ]
    }
}

The entity field gives a link to the other entity along with basic information. The matches field provides a justification for the determination that the two entities are possibly the same entity. Each match has three fields:

  • value: The normalized value that matched. This is often a modified version of an attribute.
  • source: The current entity's original version of the normalized value.
  • target: The other entity's original version of the normalized value.

In this case the two entities were matched because of a matching name and month of the birth.

# Referenced By

The referenced_by field links directly to the records that give information about the entity in question. These records are the same records that are linked to in attribute and relationship citations.

Record citations are an important way to validate the information shown in the entity response.

The first few records for Victoria Beckham are listed below:

"referenced_by": {
    "next": "b9dc2ca839c31",
    "prev": "49dc2ca839c31",
    "limit": 100,
    "size": {
        "count": 16,
        "qualifier": "eq"
    },
    "next": false,
    "data": [
      {
            "record": {
                "id": "ecdfb3f2ecc8c3797e77d5795a8066ef%2F03262039%2F1556150400000",
                "label": "UK Companies House - 4/25/2019",
                "source": "ecdfb3f2ecc8c3797e77d5795a8066ef",
                "publication_date": "2019-04-25",
                "acquisition_date": "2019-04-25",
                "references_count": 2,
                "record_url": "/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03262039%2F1556150400000"
            },
            "type": "mentions"
        },
        {
            "record": {
                "id": "ecdfb3f2ecc8c3797e77d5795a8066ef%2F03198152%2F1540252800000",
                "label": "UK Companies House - 10/23/2018",
                "source": "ecdfb3f2ecc8c3797e77d5795a8066ef",
                "publication_date": "2018-10-23",
                "acquisition_date": "2018-10-23",
                "references_count": 6,
                "record_url": "/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03198152%2F1540252800000"
            },
            "type": "mentions"
        },
        ...
    ]
}

Here's a description of the important fields, minus pagination which should be well-established at this point:

Field Path Value Description
referenced_by.data[].record.id "ecdfb3f2ecc8c3797e77d5795..." Internal Sayari ID for the record
referenced_by.data[].record.label "UK Companies House - 10/23/2018" Name for the record, includes the source and date
referenced_by.data[].record.source "ecdfb3f2ecc8c3797e77d579..." Internal Sayari ID for the source
referenced_by.data[].record.publication_date "YYYY-MM-DD" Date the record was published
referenced_by.data[].record.acquisition_date "YYYY-MM-DD" Date Sayari acquired the record
referenced_by.data[].record.references_count int Number of distant entities referenced by this record (including current entity)
referenced_by.data[].record.record_url /record/ecdfb3f2ecc8c3797e77d API URL to get information about the record
referenced_by.data[].type "about|mentions" Whether the current entity is the primary subject of the record (about) or not (mentions)

# Representations

All /entity/ calls have alternate representations. To obtain a csv version of the entity use the following request:

curl "https://api.sayari.com/v1/entity/XabunnGRTK2ieyLtP-PiUQ?csv.attributes" \
  --header "authorization: Bearer $TOKEN" --header "Accept: text/csv"
"id","attribute","value","properties","record"
"XabunnGRTK2ieyLtP-PiUQ","identifier","1111","{""type"":""id""}","aaaa/1111/2222"

The type of csv response can be set in the query string with csv.attributes returning a csv about entity attributes and csv.relationships returning a csv about entity relationships. A pdf of the entity can also be obtained with the following request:

curl "https://api.sayari.com/v1/entity/XabunnGRTK2ieyLtP-PiUQ" \
  --header "authorization: Bearer $TOKEN" --header 'Accept: application/pdf' --output entity.pdf

You can now open the file entity.pdf and see the requested entity.

# Get Traversal

The traversals endpoint includes information that is one or more relationships (one or more "hops") from the entity in question. This is useful when indirect relationships, such as ownership and control relationships, need to be explored. Instead of chaining together multiple /entity/ calls for each level of relationships, you can view indirect relationships such as ultimate beneficial ownership using a single call.

For example, a possible traversal to return all companies you can reach via Shareholder Of and Has Branch edges would look like ?relationships=shareholder_of&relationships=has_branch. Alternatively, a traversal to return all co-directors, defined as people who share directorships with each other, could look like ?min_depth=2&max_depth=2&relationships=director_of&relationships=has_director. Lastly, if you only want to explore a paginatable list of all entities reachable from a single target entity, regardless of how they are related, omit the relationships parameter, for example ?offset=100&max_depth=5.

# Downstream Holdings Traversal

If we were interested in obtaining the downstream holdings for Victoria Beckham, we could run either of the following queries:

curl "https://api.sayari.com/v1/traversal/XabunnGRTK2ieyLtP-PiUQ?relationships=shareholder_of&relationships=beneficial_owner_of&relationships=owner_of&relationships=has_subsidiary&relationships=has_branch" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

or use the shorthand /downstream endpoint:

curl "https://api.sayari.com/v1/downstream/XabunnGRTK2ieyLtP-PiUQ" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool
{
  "min_depth": 1,
  "max_depth": 6,
  "relationships": ["shareholder_of","beneficial_owner_of","owner_of","has_subsidiary","has_branch"],
  "countries": [],
  "types": [],
  "name": "",
  "watchlist": false,
  "psa": false,
  "offset": 0,
  "limit": 20,
  "next": false,
  "data": [
    {
      "target": {
        "id": "DtsJSrlshImFeZaFZrxR5Q",
        "label": "MOODY PRODUCTIONS LIMITED",
        "degree": 2,
        "pep": false,
        "sanctioned": false,
        ...,
      },
      "path": [
        {
          "field": "shareholder_of",
          "relationships": {
            "director_of": {
              "values": [
                {
                  "record": "ecdfb3f2ecc8c3797e77d5795a8066ef/03407448/1618358400000",
                  "attributes": { "position": [{ "value": "Director" }] },
                  "from_date": "2007-12-01",
                  "acquisition_date": "2021-04-14",
                  "publication_date": "2021-04-14"
                },
                {
                  "record": "ecdfb3f2ecc8c3797e77d5795a8066ef/03407448/1611100800000",
                  "attributes": { "position": [{ "value": "Director" }] },
                  "from_date": "2007-12-01",
                  "acquisition_date": "2021-01-20",
                  "publication_date": "2021-01-20"
                }
              ]
            },
            "shareholder_of": {
              "values": [
                {
                  "record": "4ea8bac1bed868e1510ffd21842e9551/98f204b19593e9a2f50aa88002d56718/1586822400000",
                  "attributes": { "position": [{ "value": "Owns 75-100% of shares" }] },
                  "date": "2016-04-06",
                  "acquisition_date": "2020-04-14",
                  "publication_date": "2020-04-14"
                },
                {
                  "record": "4ea8bac1bed868e1510ffd21842e9551/03407448/1560176240192",
                  "attributes": { "position": [{ "value": "Owns 75-100% of shares" }] },
                  "date": "2016-04-06",
                  "acquisition_date": "2019-06-10",
                  "publication_date": "2019-06-10"
                }
              ]
            }
          },
          "entity": {
            "id": "DtsJSrlshImFeZaFZrxR5Q",
            "label": "MOODY PRODUCTIONS LIMITED",
            "degree": 2,
            "pep": false,
            "sanctioned": false,
            ...,
          }
        }
      ]
    }
 ],
  "explored_count": 8
}

The target is a single entity that is reachable from Victoria Beckham through ownership edges. The path array gives a list of relationships and entities that constitute an ownership path from Victoria Beckham to VICTORIA BECKHAM LIMITED. In Sayari's GUI, this ownership path is visualized as follows:

tree

In plain english, this shows that:

  • VICTORIA CARLINE BECKHAM is a shareholder of BECKHAM BRAND HOLDINGS LIMITED
  • Which is a shareholder of VICTORIA BECKHAM HOLDINGS LIMITED
  • Which is a shareholder of VICTORIA BECKHAM LIMITED

Thus, VICTORIA CAROLINE BECKHAM is an indirect owner of VICTORIA BECKHAM LIMITED.

# Co-Directors Traversal

Traversals are useful for more than just ownership relationships. If you're interested in Victoria Beckham, it might be useful to get a list of people who appear on the same company as Victoria Beckham. To get this list, you can use a custom traversal:

curl "https://api.sayari.com/traversal/XabunnGRTK2ieyLtP-PiUQ?minDepth=2&maxDepth=2&relationships=director_of&relationships=has_director" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

Note the URL parameters here:

  • minDepth=2: The minimum number of relationships in the returned paths
  • maxDepth=2: The maximum number of relationships in the returned paths
  • relationships=director_of: A relationship type to consider
  • relationships=has_director: Another relationship type to consider

The resulting target entities under traversals[0].target as rendered in Sayari's GUI:

tree

The list of names above shows the co-directors that are found on the same company with Victoria Beckham.

In addition to the generic /traversal and the /downstream endpoints discussed above, there is also a /ubo endpoint to return indirect beneficial owners of an entity, as well as a /watchlist endpoint to return indirectly related watchlisted and pep entities.

# Get Record

Each piece of information returned in an entity response is derived from one or more records.

A record contains multiple entities. Every piece of information in a record is derived from a single source document that Sayari has acquired. These source documents are often HTML files downloaded from the internet, parts of bulk data files, or PDFs.

If Sayari has acquired an HTML web page that lists all of the directors for OCTOPUS DIRECT LIMITED, the corresponding record will have the following information:

  • The primary entity, OCTOPUS DIRECT LIMITED
  • One entity for each director

Using the record URL returned above (/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03198152%2F1540252800000), we can take a look at this information:

curl "https://api.sayari.com/v1/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03198152%2F1540252800000" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

The response contains basic information about the record and a list of entities under references.data[]:

{
    "id": "ecdfb3f2ecc8c3797e77d5795a8066ef%2F03198152%2F1540252800000",
    "label": "UK Companies House - 10/23/2018",
    "source": "ecdfb3f2ecc8c3797e77d5795a8066ef",
    "publication_date": "2018-10-23",
    "acquisition_date": "2018-10-23",
    "references_count": 6,
    "record_url": "/record/ecdfb3f2ecc8c3797e77d5795a8066ef%2F03198152%2F1540252800000",
    "references": {
        "next": false,
        "offset": 0,
        "limit": 100,
        "size": {
            "count": 6,
            "qualifier": "eq"
        },
        "data": [
            {
                "entity": {
                    "id": "XabunnGRTK2ieyLtP-PiUQ",
                    "label": "OCTOPUS DIRECT LIMITED",
                    "type": "company",
                    "entity_url": "/entity/XabunnGRTK2ieyLtP-PiUQ",
                    "identifiers": [
                        {
                            "type": "uk_company_number",
                            "value": "03198152"
                        }
                    ],
                    "countries": [
                        "GBR"
                    ],
                    "source_count": {
                        "ecdfb3f2ecc8c3797e77d5795a8066ef": {
                            "count": 1,
                            "label": "UK Companies House",
                        }
                    },
                    "relationship_count": {
                        "has_director": 5
                    }
                },
                "type": "about"
            },
            {
                "entity": {
                    "id": "XabunnGRTK2ieyLtP-PiUQ",
                    "label": "VICTORIA CAROLINE BECKHAM",
                    "type": "person",
                    "entity_url": "/v1/entity/XabunnGRTK2ieyLtP-PiUQ",
                    "identifiers": [
                        {
                            "type": "uk_person_number",
                            "value": "055967030010"
                        }
                    ],
                    "countries": [
                        "GBR"
                    ],
                    "source_count": {
                        "4ea8bac1bed868e1510ffd21842e9551": {
                            "count": 2,
                            "label": "UK Persons with Significant Control",
                        },
                        "ecdfb3f2ecc8c3797e77d5795a8066ef": {
                            "count": 14,
                            "label": "UK Companies House",
                        }
                    },
                    "relationship_count": {
                        "linked_to": 2,
                        "shareholder_of": 2,
                        "secretary_of": 1,
                        "director_of": 10
                    }
                },
                "type": "mentions"
            },
            ...
        ]
    }
}

Each entity includes information similar to what is returned by entity search. In the future the /record/ endpoint will return additional information as well, such as the relationships and attributes derived from the record.

Note that the primary subject of the record (OCTOPUS DIRECT LIMITED) is identified by references.data.type = "about".

# Download Source Document

For most of the sources that Sayari collects, we offer the raw source documents. This allows the verification of the information we provided end-to-end.

However in certain cases, when we acquire a data source from a bulk file, the source document is not available.

To demonstrate, let's search for another source.

curl "https://api.sayari.com/v1/search/record?q=\"MICHAEL+DEBONO+LIMITED\"&limit=1" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

Which gives us the search result:

{
    "offset": 0,
    "limit": 1,
    "next": true,
    "size": {
        "count": 10,
        "qualifier": "eq"
    },
    "data": [
        {
            "id": "56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851",
            "label": "Malta Companies Register - 4/1/2019",
            "source": "56cbecf2464d41b7233042b97ed7660a",
            "publication_date": "2019-04-01",
            "acquisition_date": "2019-04-01",
            "references_count": 9,
            "record_url": "/record/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851",
            "matches": {
                "name": [
                    "<em>MICHAEL</em> <em>DEBONO</em> <em>LIMITED</em>"
                ],
                "address": [
                    "<em>DEBONO</em> HOUSE, MDINA ROAD ZEBBUG ZBG06 MALTA"
                ]
            }
        }
    ]
}
curl "https://api.sayari.com/v1/record/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

Which gives us:

{
    "id": "56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851",
    "label": "Malta Companies Register - 4/1/2019",
    "source": "56cbecf2464d41b7233042b97ed7660a",
    "publication_date": "2019-04-01",
    "acquisition_date": "2019-04-01",
    "references_count": 9,
    "record_url": "/record/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851",
    "document_urls": [
        "/document/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851/file/html-company%2FC%2B10002.html",
        "/document/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851/file/html-people%2FC%2B10002.html",
        "/document/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851/file/html-capital%2FC%2B10002.html"
    ],
    "references": {...}
}

The files available for download are listed in the document_urls array. This is given as an array, since we sometimes derive a single record from multiple files.

The /document/:record-id/file endpoint will lead to the original document in the original database from which we obtained it (if a direct link would be functional) or a landing page that will allow the user to navigate to the record, if a direct link is not feasible.

Also the /document/:record-id/file/:document-id endpoint will lead you to other documents for the record given the document id

We started by searching for "MICHAEL DEBONO LIMITED," so let's grep for this name in the first file listed:

curl "https://api.sayari.com/document/56cbecf2464d41b7233042b97ed7660a%2FC-10002%2F1568730581851/file/html-company%2FC%2B10002.html" \
   --header "authorization: Bearer $TOKEN" | grep "MICHAEL DEBONO LIMITED" -A 1 -B 1

Which finds the mentions of MICHAEL DEBONO LIMITED in the raw source document:

-
<span>
    MICHAEL DEBONO LIMITED
</span>
--
<td style="width:25%" nowrap class="labelLeft" valign="top">Company Name</td>
    <td>MICHAEL DEBONO LIMITED</td>
</tr>

# Types Lookup

If you need a list of values for a particular part of the ontology (like identifier) use the /type/:field endpoint

curl "https://api.sayari.com/types/identifier?limit=5" \
  --header "authorization: Bearer $TOKEN" | python -m json.tool

This will give the following response:

{
    "offset": 0,
    "limit": 5,
    "size": {
        "count": 363,
        "qualifier": "eq"
    },
    "next": true,
    "data": [
        {
            "id": "afg_business_license",
            "label": "Afg Business License"
        },
        {
            "id": "afg_passport",
            "label": "Afg Passport"
        },
        {
            "id": "afghan_tin_number",
            "label": "Afghan Tin Number"
        },
        {
            "id": "alb_registration_number",
            "label": "Alb Registration Number"
        },
        {
            "id": "alb_tax_id",
            "label": "Alb Tax Id"
        }
    ]
}

# See API Usage

If at any point in time you want to see the number of API credits consumed by your account use the /usage endpoint.

curl "https://api.sayari.com/usage" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

This will give the following response:

{
  "paths": [
    {
      "path": "/search/entity",
      "views": 193,
      "credits": 0
    },
    {
      "path": "/record",
      "views": 21,
      "credits": 0
    },
    {
      "path": "/entity",
      "views": 39,
      "credits": 40
    }
  ],
  "credits": 411,
  "since": "2020-02-14T00:34:33.585525Z",
  "total": true
}

As you can see this user consumed 411 API credits between the /record and /entity endpoints. The specific number of calls in the time period are denoted by the views along with the path value and associated credits. In this example, since 2020-02-14, the user has consumed 411 credits which corresponds to total usage since the account was created. This will be specified by the total field.

If you want to change the time period add a since parameter to the query string. For example:

curl "https://api.sayari.com/usage?since=2020-05-25" \
   --header "authorization: Bearer $TOKEN" | python -m json.tool

This will give the following response:

{
  "paths": [
    {
      "path": "/search/entity",
      "views": 193,
      "credits": 0
    },
    {
      "path": "/record",
      "views": 12,
      "credits": 0
    },
    {
      "path": "/entity",
      "views": 20,
      "credits": 40
    }
  ],
  "credits": 212,
  "since": "2020-05-25T00:34:33.585525Z",
  "total": false
}

Here we see usage since 2020-05-25. If the query is omitted, total usage is calculated. Note that API usage statistics are not necessarily aggregated over every date so if the provided query is not found, the next closest will be returned.

# Conclusion

This concludes the API walkthrough. Check out this page for more information.