Calling Fathom’s Integration API Programmatically

← Back to Documentation Home


Prerequisites

Before you can access the Fathom Integration API programmatically, you’ll need to contact Fathom to obtain:

Please confirm your exact hostname with Fathom, as it may vary based on your deployment. Also, depending on the security requirements of your enterprise deployment, additional criteria might be necessary to enable access across the firewall.


Getting an API Access Token

Before making API calls, you need to obtain an OAuth2 access token using your client credentials.

Python Example

import requests

def get_access_token():
    """
    Obtain an OAuth2 access token using client credentials.
    Returns the access token string.
    """
    # Replace {your-instance} with your actual hostname
    auth_url = "https://auth.{your-instance}.fathom.one/oauth2/token"
    
    auth_headers = {
        "Content-Type": "application/x-www-form-urlencoded",
    }
    
    data = {
        "grant_type": "client_credentials",
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "scope": "https://{your-instance}.fathom.one/api/integrations",
    }
    
    response = requests.post(auth_url, headers=auth_headers, data=data)
    
    if response.status_code == 200:
        return response.json()['access_token']
    else:
        raise Exception(f"Failed to get token: {response.status_code} - {response.text}")

Bash Example

#!/bin/bash

# Replace these with your actual values
CLIENT_ID="YOUR_CLIENT_ID"
CLIENT_SECRET="YOUR_CLIENT_SECRET"
HOSTNAME="your-instance"

# Get access token
AUTH_URL="https://${HOSTNAME}.fathom.one/oauth2/token"
SCOPE="https://${HOSTNAME}.fathom.one/api/integrations"

ACCESS_TOKEN=$(curl -s -X POST "$AUTH_URL" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "scope=${SCOPE}" \
  | jq -r '.access_token')

echo "Access Token: $ACCESS_TOKEN"

Calling the GraphQL API

Once you have an access token, you can make GraphQL queries to the Fathom Integration API.

Python Example

import requests
import json

def make_api_call(access_token: str, query: str, variables: dict):
    """
    Execute a GraphQL query against the Fathom Integration API.
    
    Args:
        access_token: OAuth2 access token
        query: GraphQL query string
        variables: Dictionary of query variables
    
    Returns:
        The data response from the API
    """
    # Replace {your-instance} with your actual hostname
    api_url = "https://{your-instance}.fathom.one/api/integrations"
    
    headers = {
        "content-type": "application/json",
        "authorization": f"Bearer {access_token}"
    }
    
    payload = [
        {
            "variables": variables,
            "query": query,
        }
    ]
    
    response = requests.post(api_url, headers=headers, json=payload)
    
    if response.status_code == 200:
        data = json.loads(response.text)[0]
        
        if "errors" in data:
            print("GraphQL Errors:", data['errors'])
            return None
        
        return data['data']
    else:
        raise Exception(f"API call failed: {response.status_code} - {response.text}")


# Example usage
if __name__ == "__main__":
    # Get access token
    token = get_access_token()
    
    # Example query: Get recent publication events
    query = """
    query RecentEvents($days: Int!) {
        recentPublicationEvents(lastNDays: $days) {
            __typename
            id
            signerEmail
            signatureId
            datasetId
            branchId
            timestampIso8601
        }
    }
    """
    
    variables = {"days": 7}
    
    # Make API call
    result = make_api_call(token, query, variables)
    print(json.dumps(result, indent=2))

Bash Example

#!/bin/bash

# Assumes ACCESS_TOKEN is already set from previous step
# Replace with your actual hostname
HOSTNAME="your-instance"
API_URL="https://${HOSTNAME}.fathom.one/api/integrations"

# Example GraphQL query
QUERY='query RecentEvents($days: Int!) {
  recentPublicationEvents(lastNDays: $days) {
    __typename
    id
    signerEmail
    signatureId
    datasetId
    branchId
    timestampIso8601
  }
}'

# Query variables
VARIABLES='{"days": 7}'

# Make GraphQL API call
curl -X POST "$API_URL" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d "[{\"query\": $(echo "$QUERY" | jq -Rs .), \"variables\": $VARIABLES}]" \
  | jq '.'

Complete Working Example

Here’s a complete Python script that demonstrates the full workflow:

import requests
import json

class FathomAPIClient:
    def __init__(self, hostname: str, client_id: str, client_secret: str):
        """
        Initialize the Fathom API client.
        
        Args:
            hostname: Your Fathom instance hostname (e.g., "your-instance")
            client_id: Your OAuth2 client ID
            client_secret: Your OAuth2 client secret
        """
        self.hostname = hostname
        self.client_id = client_id
        self.client_secret = client_secret
        self.base_url = f"https://{hostname}.fathom.one"
        self.access_token = None
    
    def authenticate(self):
        """Obtain and store an OAuth2 access token."""
        auth_url = f"{self.base_url}/oauth2/token"
        
        auth_headers = {
            "Content-Type": "application/x-www-form-urlencoded",
        }
        
        data = {
            "grant_type": "client_credentials",
            "client_id": self.client_id,
            "client_secret": self.client_secret,
            "scope": f"{self.base_url}/api/integrations",
        }
        
        response = requests.post(auth_url, headers=auth_headers, data=data)
        
        if response.status_code == 200:
            self.access_token = response.json()['access_token']
            print("✓ Authentication successful")
        else:
            raise Exception(f"Authentication failed: {response.status_code} - {response.text}")
    
    def query(self, query: str, variables: dict = None):
        """
        Execute a GraphQL query.
        
        Args:
            query: GraphQL query string
            variables: Optional dictionary of query variables
        
        Returns:
            The data response from the API
        """
        if not self.access_token:
            self.authenticate()
        
        api_url = f"{self.base_url}/api/integrations"
        
        headers = {
            "content-type": "application/json",
            "authorization": f"Bearer {self.access_token}",
        }
        
        payload = [
            {
                "query": query,
                "variables": variables or {},
            }
        ]
        
        response = requests.post(api_url, headers=headers, json=payload)
        
        if response.status_code == 200:
            data = json.loads(response.text)[0]
            
            if "errors" in data:
                print("GraphQL Errors:", json.dumps(data['errors'], indent=2))
                return None
            
            return data['data']
        else:
            raise Exception(f"API call failed: {response.status_code} - {response.text}")


# Example usage
if __name__ == "__main__":
    # Initialize client
    client = FathomAPIClient(
        hostname="your-instance",
        client_id="YOUR_CLIENT_ID",
        client_secret="YOUR_CLIENT_SECRET"
    )
    
    # Example 1: Get subscribed dataset metadata
    print("\n--- Getting Subscribed Dataset Metadata ---")
    metadata_query = """
    query {
        listSubscribedDatasetMetadata {
            id
            datasetName
            datasetColumns {
                id
                columnName
                valueType
            }
        }
    }
    """
    
    result = client.query(metadata_query)
    print(json.dumps(result, indent=2))
    
    # Example 2: Get recent publication events
    print("\n--- Getting Recent Publication Events ---")
    events_query = """
    query RecentEvents($days: Int!) {
        recentPublicationEvents(lastNDays: $days) {
            id
            signerEmail
            datasetId
            timestampIso8601
        }
    }
    """
    
    result = client.query(events_query, variables={"days": 7})
    print(json.dumps(result, indent=2))

Important Notes

  1. Keep your credentials secure: Never commit your client_id or client_secret to version control. Use environment variables or secure configuration management.

  2. Token reuse and expiration: Fathom requires that you reuse access tokens until they expire. Do NOT request a new token for every API call. Store the access token and use it for multiple requests until it expires, then request a new one. Implement token refresh logic in production applications that checks expiration before making requests.

  3. Error handling: Always check for both HTTP errors and GraphQL errors in the response.

  4. Rate limiting: Be mindful of API rate limits. Implement appropriate retry logic with exponential backoff for production use.

  5. User-Agent header: The user-agent header helps Fathom identify and support your integration. It may be required depending on the security configuration for your deployment.


For more information about available queries and the GraphQL schema, see the GraphQL Documentation.

For API updates and version history, see the API Release Notes.