# 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.
# Entity Search
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.
# Record Search
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:
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 pathsmaxDepth=2
: The maximum number of relationships in the returned pathsrelationships=director_of
: A relationship type to considerrelationships=has_director
: Another relationship type to consider
The resulting target entities under traversals[0].target
as rendered in Sayari's GUI:
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.
← API