Calling Fathom’s Integration API Programmatically
Prerequisites
Before you can access the Fathom Integration API programmatically, you’ll need to contact Fathom to obtain:
- Client ID – Your unique application identifier
- Client Secret – Your application’s secret key (keep this secure!)
- API Hostname – The specific hostname for your Fathom instance
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
-
Keep your credentials secure: Never commit your
client_idorclient_secretto version control. Use environment variables or secure configuration management. -
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.
-
Error handling: Always check for both HTTP errors and GraphQL errors in the response.
-
Rate limiting: Be mindful of API rate limits. Implement appropriate retry logic with exponential backoff for production use.
-
User-Agent header: The
user-agentheader 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.