Linking Your Data Using the Relationships API

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].

  1. Import the requests library in Python to help call the API.
  2. Construct the URL, making sure to provide your specific<tenant-name> and the tableId for your data. The tableId is available on the data product's Manage System of Record page (see Configuring a Data Product for Tamr RealTime).
  3. 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.

  1. Define the URL for the relationships endpoint.
  2. Create the payload, which specifies the link you want to create. You need:
    • fromTableId and fromRecordId: The source record of the relationship (child record).
    • toTableId and toRecordId: 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.
  3. Set the headers, including your X-API-KEY and the content-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:

fromRecordIdtoRecordId
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.

  1. Construct the URL including the relationshipId of the relationship to update. Retrieve the relationshipId by using the list relationships endpoint.
  2. Create the payload with the fields you want to change. In this example, we are updating the destination record (toRecordId).
  3. 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"
  }
}

© 2025, Tamr, Inc. All rights reserved.

License Agreement | Privacy Policy | Data Security Policy| AI Chatbot Disclaimer