The Relationships API helps you create a web of linked information that mirrors real-world connections within your data. For instance, you might link members of a household, healthcare providers and organizations, or subsidiary companies and their headquarters.
This topic provides Python examples to call the API and establish parent-child relationships between company records.
Viewing Available Relationship Types
First, check which relationship types have already been configured on your tenant using a GET request to list relationship types.
If you need to set up new relationship types, please contact [email protected].
- Import the
requests
library in Python to help call the API. - Construct the URL, making sure to provide your specific
<tenant-name>
and thetableId
for your data. ThetableId
is available on the data product's Manage System of Record page (see Configuring a Data Product for Tamr RealTime). - Set the headers, including your
X-API-KEY
for authentication.
import requests
url = "https\://<tenant-name>.tamr.cloud/api/v1alpha1/relationships/types:list?tableId=`tbl_<id>"
headers = {
"accept": "application/json",
"X-API-KEY": "example-api-key"
}
response = requests.get(url, headers=headers)
print(response.text)
The API response includes all configured relationship types.
The example below shows one relationship type for linking a child company to its parent, with the relationship defined by the forwardName
("is child of") and reverseName
("is parent of").
{
"relationshipTypes": [
{
"relationshipTypeId": "reltyp_<id>",
"versionId": "32969596",
"forwardName": "is child of",
"reverseName": "is parent of",
"description": "Represents a child/parent relationship between companies.",
"createTime": "2025-09-23T16:33:39.118Z",
"updateTime": "2025-09-25T19:54:19.452Z"
}
]
}
Creating New Relationships
You can create new relationships by:
- Using the API to link two records
- Automating relationship creation
- Uploading relationships in bulk using a workflow
Linking Two Records
Once you know the relationshipTypeId
, you can make a POST
request to create new relationships between records in the same table or between different tables.
This example demonstrates how to create relationships between a child and parent company in the same table.
- Define the URL for the relationships endpoint.
- Create the
payload
, which specifies the link you want to create. You need:fromTableId
andfromRecordId
: The source record of the relationship (child record).toTableId
andtoRecordId
: The destination record of the relationship (parent record).relationshipTypeId
: The ID for the type of relationship you're creating, which you found in the previous step.
- Set the headers, including your
X-API-KEY
and thecontent-type
.
import requests
url = "https://<tenant-name>.tamr.cloud/api/v1alpha1/relationships"
payload = {
"fromTableId": "tbl_<id_1>",
"fromRecordId": "rec_<id_a>",
"toTableId": "tbl_<id_1>",
"toRecordId": "rec_<id_b>",
"relationshipTypeId": "reltyp_<id>"
}
headers = {
"accept": "application/json",
"X-API-KEY": "example-api-key",
"content-type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
A successful request returns a response confirming the details of the relationship that was just created.
{
"relationship": {
"relationshipId": "rel_<id>",
"versionId": "1",
"fromTableId": "tbl_<id_1>",
"fromRecordId": "rec_<id_a>",
"toTableId": "tbl_<id_1>",
"toRecordId": "rec_<id_b>",
"relationshipTypeId": "reltyp_<id>",
"details": {},
"createTime": "2025-10-14T17:28:48.314Z",
"updateTime": "2025-10-14T17:28:49.314Z"
}
}
Automating Relationship Creation
Instead of making single API calls, you can build an automated script or integration to read a list of relationship pairs and dynamically construct the JSON payload.
For example, from a CSV file containing columns for the fromRecordId
and toRecordId
, the script would loop through each pair, construct the JSON payload and execute a POST
request to the relationships endpoint for every row in your file.
For large-scale processes, it's important to implement error handling to log and manage any failed requests, and to respect potential API rate limits by adding small delays between calls. This helps to ensure that thousands of relationships can be created without overwhelming the system.
Example CSV:
fromRecordId | toRecordId |
---|---|
rec_<id_a> | rec_<id_b> |
rec_<id_c> | rec_<id_d> |
rec_<id_e> | rec_<id_f> |
rec_<id_g> | rec_<id_h> |
rec_<id_i> | rec_<id_j> |
Example Python script:
import requests
import csv
import time
# --- Configuration ---
# Replace with your specific details
TENANT_NAME = "<tenant-name>"
TABLE_ID = "tbl_<id>"
RELATIONSHIP_TYPE_ID = "reltyp_<id>"
CSV_FILE_PATH = "relationships_to_create.csv"
API_KEY = "example-api-key"
# --- API Details ---
API_URL = f"https://{TENANT_NAME}.tamr.cloud/api/v1alpha1/relationships"
HEADERS = {
"accept": "application/json",
"X-API-KEY": API_KEY,
"content-type": "application/json"
}
def create_relationship(from_record_id, to_record_id, row_num):
"""
Calls the relationships API to create a single relationship.
Args:
from_record_id (str): The ID of the source record.
to_record_id (str): The ID of the destination record.
row_num (int): The current row number from the CSV for logging.
"""
payload = {
"fromTableId": TABLE_ID,
"fromRecordId": from_record_id,
"toTableId": TABLE_ID,
"toRecordId": to_record_id,
"relationshipTypeId": RELATIONSHIP_TYPE_ID
}
try:
response = requests.post(API_URL, json=payload, headers=HEADERS)
# Check if the request was successful
if response.status_code == 200:
print(f"SUCCESS: Row {row_num} | Relationship created from {from_record_id} to {to_record_id}")
# print("Response:", response.json()) # Uncomment for full response details
else:
print(f"ERROR: Row {row_num} | Failed to create relationship for {from_record_id}.")
print(f"Status Code: {response.status_code}")
print(f"Response Body: {response.text}")
except requests.exceptions.RequestException as e:
print(f"ERROR: Row {row_num} | A network error occurred for {from_record_id}.")
print(f"Error details: {e}")
def process_csv_and_create_relationships():
"""
Reads the specified CSV file and initiates the relationship creation for each row.
"""
print(f"\nStarting to process file: {CSV_FILE_PATH}...")
try:
with open(CSV_FILE_PATH, mode='r', encoding='utf-8') as csvfile:
# Using DictReader to easily access columns by name
reader = csv.DictReader(csvfile)
# enumerate provides a counter (row_num starts at 2 to account for header)
for i, row in enumerate(reader, start=2):
from_id = row.get("fromRecordId")
to_id = row.get("toRecordId")
if not from_id or not to_id:
print(f"WARNING: Row {i} | Skipping due to missing 'fromRecordId' or 'toRecordId'.")
continue
create_relationship(from_id, to_id, i)
# IMPORTANT: Add a delay to avoid overwhelming the API (rate limiting). Adjust the sleep time as needed based on API limits.
time.sleep(0.5)
print("\nProcessing complete.")
except FileNotFoundError:
print(f"FATAL ERROR: The file '{CSV_FILE_PATH}' was not found.")
print("Please ensure the CSV file is in the same directory as the script.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# --- Main execution block ---
if __name__ == "__main__":
process_csv_and_create_relationships()
Creating Relationships through Bulk Upload
You can configure a workflow to import relationships between records as part of a bulk process. See Importing Relationships for instructions.
Updating Existing Relationships
You can make a PUT
request to update relationships between two records. For example, you can link a record to a different parent in the same table.
You need the unique relationshipTypeId
for the relationship you want to modify.
- Construct the URL including the
relationshipId
of the relationship to update. Retrieve therelationshipId
by using the list relationships endpoint. - Create the
payload
with the fields you want to change. In this example, we are updating the destination record (toRecordId
). - Set the headers with your authentication details.
import requests
url = "https://<tenant-name>.tamr.cloud/api/v1alpha1/relationships/rel_<id>"
payload = {
"relationshipTypeId": "reltyp_<id>",
"fromTableId": "tbl_<id_1>",
"fromRecordID": "rec_<id_a>",
"toTableId": "tbl_<id_1>",
"toRecordID": "rec_<id_c>"
}
headers = {
"accept": "application/json",
"X-API-KEY": "example-api-key",
"content-type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)
A successful request returns the full, updated relationship object.
{
"relationship": {
"relationshipId": "rel_<id>",
"versionId": "1",
"fromTableId": "tbl_<id_1>",
"fromRecordId": "rec_<id_a>",
"toTableId": "tbl_<id_1>",
"toRecordId": "rec_<id_c>",
"relationshipTypeId": "reltyp_<id>",
"details": {},
"createTime": "2025-10-02T14:44:31.287Z",
"updateTime": "2025-10-02T14:44:32.287Z"
}
}