All posts
Guide

Using the SearchFit SDK: Node, Python, and Go Examples

Step-by-step guide to integrating SearchFit SDK in Node.js, Python, and Go. Learn API authentication, tracking AI visibility, and building AEO workflows.

KKevin18 minutes read

Using the searchfit sdk: Node, Python, and Go Examples

Prerequisites and Setup

Before you start integrating the SearchFit SDK into your application, you'll need a few things in place. First, you need an active SearchFit account, if you don't have one yet, sign up at SearchFit to get started. Once your account is live, you'll have access to your API credentials, which include your API key and workspace ID. These credentials are non-negotiable; they authenticate every request your application makes to the SearchFit platform.

You'll also need the appropriate runtime environment installed on your machine. For Node.js projects, ensure you have Node.js Official Documentation installed (version 14 or higher is recommended). Python developers should have Python Official Documentation 3.8 or later. Go developers need Go Official Documentation 1.16 or newer. Each language has its own package manager, npm for Node.js (available via NPM Official Registry), pip for Python (via Python Package Index), and go get for Go (discoverable on Go Package Discovery).

Your development environment should also include a code editor and terminal access. You'll be making HTTP requests to SearchFit's API endpoints, so familiarity with REST APIs and JSON payloads is helpful. If you're building client-side JavaScript applications, understanding the MDN Web Docs: Fetch API will serve you well.

Lastly, have your SearchFit workspace ID and API key handy. These should be stored securely, never hardcode them into your source code. Use environment variables or a secrets management system instead. This is a critical security practice, especially if you're building production systems that track your brand visibility across ChatGPT, Perplexity, Gemini, Claude, and other AI search engines.

Understanding the SearchFit SDK Architecture

The SearchFit SDK is designed to simplify interaction with the SearchFit API across multiple programming languages. At its core, the SDK handles authentication, request formatting, error handling, and response parsing. Rather than constructing raw HTTP requests, you use language-specific methods that abstract away boilerplate code.

The SDK exposes several key modules and classes depending on your language of choice. In Node.js, you'll import the main SearchFit client; in Python, you'll instantiate a client object; in Go, you'll work with a struct-based interface. All three share a common philosophy: provide intuitive methods for the most common operations, tracking brand mentions across AI engines, fetching visibility analytics, generating content recommendations, and managing your AEO (Answer Engine Optimization) strategy.

Understanding this architecture matters because it shapes how you'll write code. The SDK doesn't just wrap HTTP calls; it manages connection pooling, handles rate limiting gracefully, and provides built-in retry logic. When you make a request through the SDK, it's already handling authentication headers, JSON serialization, and error responses. This means you can focus on your business logic, like analyzing which AI search engines are citing your content and where you're losing visibility to competitors.

The SDK also includes type definitions (in TypeScript-compatible Node.js packages and Python type hints) that help catch errors at development time rather than runtime. This is especially valuable when you're building complex workflows that depend on accurate data about your AI visibility across multiple platforms.

Installing the SearchFit SDK for Node.js

Getting the SearchFit SDK running in Node.js is straightforward. Open your terminal and navigate to your project directory. If you haven't initialized a Node.js project yet, run npm init -y to create a package.json file with default settings.

Next, install the SearchFit SDK package from NPM Official Registry by running:

npm install searchfit

This command downloads the SDK and adds it to your node_modules directory, along with any dependencies it requires. The package.json file is updated automatically to track this dependency.

Once installed, verify the installation by creating a simple test file. Create a file called test.js and add this basic import:

const SearchFit = require('searchfit');

console.log('SearchFit SDK loaded successfully');

Run this file with node test.js. If you see the success message, the SDK is properly installed.

For TypeScript projects, the SearchFit SDK includes type definitions out of the box. If you're using TypeScript, you can import and use the SDK with full type safety:

import SearchFit from 'searchfit';

const client = new SearchFit({
apiKey: process.env.SEARCHFIT_API_KEY,
workspaceId: process.env.SEARCHFIT_WORKSPACE_ID,
});

Storing your API credentials in environment variables (loaded from a .env file using a package like dotenv) keeps them out of your source code. This is essential for security.

Authenticating with the SearchFit API in Node.js

Authentication is the first step in any SDK integration. The SearchFit API uses API key-based authentication, which is simple and secure when handled properly. In Node.js, you initialize the SearchFit client with your credentials.

Create a file called auth.js:

require('dotenv').config();
const SearchFit = require('searchfit');

const client = new SearchFit({
apiKey: process.env.SEARCHFIT_API_KEY,
workspaceId: process.env.SEARCHFIT_WORKSPACE_ID,
});

module.exports = client;

Your .env file should look like this (never commit this to version control):

SEARCHFIT_API_KEY=your_actual_api_key_here
SEARCHFIT_WORKSPACE_ID=your_workspace_id_here

When you initialize the client, the SDK automatically includes your API key in the Authorization header for every request. This authentication persists for the lifetime of the client object, so you typically create it once and reuse it throughout your application.

If authentication fails, perhaps due to an invalid API key, the SDK will throw an error. You should handle this gracefully:

try {
const client = new SearchFit({
apiKey: process.env.SEARCHFIT_API_KEY,
workspaceId: process.env.SEARCHFIT_WORKSPACE_ID,
});
console.log('Authentication successful');
} catch (error) {
console.error('Authentication failed:', error.message);
process.exit(1);
}

Once authenticated, you're ready to make API calls to track your brand visibility across AI search engines like ChatGPT, Perplexity, and Gemini.

Tracking AI Visibility with Node.js Examples

Now that you're authenticated, let's track your brand's visibility across AI search engines. This is where SearchFit delivers real value, you can see exactly which AI platforms are citing your content, which queries mention your brand, and where you're losing visibility to competitors.

Create a file called track-visibility.js:

const client = require('./auth');

async function trackBrandVisibility() {
try {
// Get visibility data for your tracked brands
const visibility = await client.tracking.getBrandVisibility({
engines: ['chatgpt', 'perplexity', 'gemini', 'claude'],
timeRange: '30d', // Last 30 days
});

console.log('Brand Visibility Across AI Engines:');
console.log(JSON.stringify(visibility, null, 2));

// Analyze which engines are citing your content
visibility.engines.forEach((engine) => {
console.log(`\n${engine.name}:`);
console.log(`  Citations: ${engine.citationCount}`);
console.log(`  Visibility Score: ${engine.visibilityScore}`);
console.log(`  Top Queries: ${engine.topQueries.join(', ')}`);
});

return visibility;
} catch (error) {
console.error('Error tracking visibility:', error);
}
}

trackBrandVisibility();

This code retrieves your brand's visibility metrics across multiple AI search engines. The response includes citation counts, visibility scores, and the top queries that trigger your brand mentions. This data is critical for understanding your AEO performance.

You can also drill deeper into specific engines. For example, if you want to see how Perplexity is ranking your content:

async function trackPerplexityVisibility() {
try {
const perplexityData = await client.tracking.getEngineVisibility('perplexity', {
timeRange: '7d', // Last 7 days
includeCompetitors: true,
});

console.log('Perplexity Visibility:');
console.log(`Your Brand Citations: ${perplexityData.yourCitations}`);
console.log(`Competitor Citations: ${perplexityData.competitorCitations}`);
console.log(`Market Share: ${perplexityData.marketShare}%`);
console.log(`\nTop Performing Content:`);
perplexityData.topContent.forEach((item) => {
console.log(`  - ${item.title} (${item.citationCount} citations)`);
});
} catch (error) {
console.error('Error:', error);
}
}

trackPerplexityVisibility();

This second example shows you're losing visibility to competitors on Perplexity. This insight drives your content strategy, you know exactly where to focus your AEO efforts.

Installing and Authenticating the SearchFit SDK for Python

Python developers follow a similar path, but with Python-specific tooling. First, ensure you have pip installed (it comes with Python 3.4 and later). Then, install the SearchFit SDK from Python Package Index:

pip install searchfit

Verify the installation by opening a Python shell and importing the module:

import searchfit
print("SearchFit SDK loaded successfully")

Now create a file called auth.py to handle authentication:

import os
from searchfit import SearchFitClient
from dotenv import load_dotenv

load_dotenv()

client = SearchFitClient(
api_key=os.getenv('SEARCHFIT_API_KEY'),
workspace_id=os.getenv('SEARCHFIT_WORKSPACE_ID')
)

Your .env file remains the same. Python's dotenv package (install with pip install python-dotenv) loads environment variables from the .env file, keeping credentials out of your source code.

Test the authentication with a simple script:

try:
client = SearchFitClient(
api_key=os.getenv('SEARCHFIT_API_KEY'),
workspace_id=os.getenv('SEARCHFIT_WORKSPACE_ID')
)
print("Authentication successful")
except Exception as e:
print(f"Authentication failed: {str(e)}")

If this runs without errors, you're ready to make API calls.

Tracking AI Visibility with Python Examples

Python's syntax is often more readable than JavaScript, which makes complex data analysis workflows cleaner. Here's how to track your brand visibility:

from auth import client
from datetime import datetime, timedelta

def track_brand_visibility():
try:
# Get visibility data for the last 30 days
visibility = client.tracking.get_brand_visibility(
engines=['chatgpt', 'perplexity', 'gemini', 'claude', 'grok'],
time_range='30d'
)

print("Brand Visibility Across AI Engines:")
print(f"Report Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("-" * 50)

for engine in visibility['engines']:
print(f"\n{engine['name'].upper()}")
print(f"  Citations: {engine['citation_count']}")
print(f"  Visibility Score: {engine['visibility_score']}/100")
print(f"  Top Queries:")
for query in engine['top_queries']:
print(f"    - {query['query']} ({query['frequency']} mentions)")

return visibility
except Exception as e:
print(f"Error tracking visibility: {str(e)}")

if __name__ == "__main__":
track_brand_visibility()

This script retrieves your visibility data and formats it for easy reading. You can extend this to save the data to a CSV file for further analysis:

import csv
from datetime import datetime

def export_visibility_to_csv():
try:
visibility = client.tracking.get_brand_visibility(
engines=['chatgpt', 'perplexity', 'gemini', 'claude'],
time_range='30d'
)

filename = f"visibility_report_{datetime.now().strftime('%Y%m%d')}.csv"

with open(filename, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Engine', 'Citations', 'Visibility Score', 'Top Query'])

for engine in visibility['engines']:
top_query = engine['top_queries'][0]['query'] if engine['top_queries'] else 'N/A'
writer.writerow([
engine['name'],
engine['citation_count'],
engine['visibility_score'],
top_query
])

print(f"Report exported to {filename}")
except Exception as e:
print(f"Error exporting report: {str(e)}")

if __name__ == "__main__":
export_visibility_to_csv()

Now you have a repeatable process for generating visibility reports. You can schedule this script to run daily and track how your AEO efforts are paying off.

Installing and Authenticating the SearchFit SDK for Go

Go's approach to package management is different from Node.js and Python. Go uses modules and the go get command to manage dependencies. First, initialize a Go module in your project directory:

go mod init github.com/yourusername/searchfit-example

Then, add the SearchFit SDK:

go get github.com/searchfit/go-sdk

Go automatically downloads the package and updates your go.mod file. You can verify the installation by checking your go.mod file, which now lists the SearchFit SDK as a dependency.

Create a file called auth.go:

package main

import (
"os"
"github.com/searchfit/go-sdk"
)

func getSearchFitClient() *searchfit.Client {
client := searchfit.NewClient(
os.Getenv("SEARCHFIT_API_KEY"),
os.Getenv("SEARCHFIT_WORKSPACE_ID"),
)
return client
}

Load your environment variables using a package like godotenv:

go get github.com/joho/godotenv

Then modify your auth.go:

package main

import (
"log"
"os"
"github.com/joho/godotenv"
"github.com/searchfit/go-sdk"
)

func init() {
if err := godotenv.Load(); err != nil {
log.Println("No .env file found, using system environment variables")
}
}

func getSearchFitClient() *searchfit.Client {
apiKey := os.Getenv("SEARCHFIT_API_KEY")
workspaceID := os.Getenv("SEARCHFIT_WORKSPACE_ID")

if apiKey == "" || workspaceID == "" {
log.Fatal("SEARCHFIT_API_KEY and SEARCHFIT_WORKSPACE_ID environment variables are required")
}

client := searchfit.NewClient(apiKey, workspaceID)
return client
}

Test the authentication:

package main

import (
"fmt"
"log"
)

func main() {
client := getSearchFitClient()

if client == nil {
log.Fatal("Failed to initialize SearchFit client")
}

fmt.Println("Authentication successful")
}

Run this with go run main.go auth.go. If authentication succeeds, you're ready to track visibility.

Tracking AI Visibility with Go Examples

Go's concurrency model makes it excellent for fetching data from multiple AI engines in parallel. Here's how to track visibility across all platforms simultaneously:

package main

import (
"context"
"fmt"
"log"
"sync"
"github.com/searchfit/go-sdk"
)

func trackBrandVisibility(client *searchfit.Client) {
ctx := context.Background()

engines := []string{"chatgpt", "perplexity", "gemini", "claude", "grok"}
results := make(map[string]*searchfit.EngineVisibility)
var mu sync.Mutex
var wg sync.WaitGroup

// Fetch visibility data for each engine concurrently
for _, engine := range engines {
wg.Add(1)
go func(engineName string) {
defer wg.Done()

visibility, err := client.Tracking.GetEngineVisibility(ctx, engineName, &searchfit.VisibilityOptions{
TimeRange: "30d",
})

if err != nil {
log.Printf("Error fetching %s visibility: %v", engineName, err)
return
}

mu.Lock()
results[engineName] = visibility
mu.Unlock()
}(engine)
}

wg.Wait()

// Print results
fmt.Println("Brand Visibility Across AI Engines:")
fmt.Println("===================================")

for engine, data := range results {
fmt.Printf("\n%s:\n", engine)
fmt.Printf("  Citations: %d\n", data.CitationCount)
fmt.Printf("  Visibility Score: %.1f%%\n", data.VisibilityScore)
fmt.Printf("  Market Share: %.1f%%\n", data.MarketShare)
}
}

func main() {
client := getSearchFitClient()
trackBrandVisibility(client)
}

The sync.WaitGroup ensures all goroutines complete before printing results. This concurrent approach is much faster than fetching engine data sequentially.

You can also drill down into specific queries:

func trackQueryPerformance(client *searchfit.Client, query string) {
ctx := context.Background()

queryData, err := client.Tracking.GetQueryVisibility(ctx, query, &searchfit.QueryOptions{
TimeRange: "7d",
IncludeCompetitors: true,
})

if err != nil {
log.Fatalf("Error fetching query data: %v", err)
}

fmt.Printf("Query: %s\n", query)
fmt.Printf("Your Citations: %d\n", queryData.YourCitations)
fmt.Printf("Competitor Citations: %d\n", queryData.CompetitorCitations)
fmt.Printf("\nTop Performing Content:\n")

for _, content := range queryData.TopContent {
fmt.Printf("  - %s (%d citations)\n", content.Title, content.CitationCount)
}
}

This function shows which queries are driving your visibility and which competitors are outranking you. This is actionable intelligence for your AEO strategy.

Fetching Analytics and Performance Data

Beyond simple visibility tracking, SearchFit provides detailed analytics that help you understand your performance trends. Let's explore how to fetch this data across all three languages.

In Node.js:

const client = require('./auth');

async function getAnalytics() {
try {
const analytics = await client.analytics.getPerformanceMetrics({
timeRange: '90d',
metrics: ['citations', 'visibility_score', 'traffic_impact', 'competitor_share'],
groupBy: 'engine',
});

console.log('Performance Metrics (Last 90 Days):');
analytics.metrics.forEach((metric) => {
console.log(`\n${metric.name}:`);
console.log(`  Current: ${metric.current}`);
console.log(`  Previous Period: ${metric.previous}`);
console.log(`  Change: ${metric.changePercent > 0 ? '+' : ''}${metric.changePercent}%`);
});

return analytics;
} catch (error) {
console.error('Error fetching analytics:', error);
}
}

getAnalytics();

In Python:

from auth import client
import json

def get_analytics():
try:
analytics = client.analytics.get_performance_metrics(
time_range='90d',
metrics=['citations', 'visibility_score', 'traffic_impact', 'competitor_share'],
group_by='engine'
)

print("Performance Metrics (Last 90 Days):")
print(json.dumps(analytics, indent=2))

# Calculate trends
for metric in analytics['metrics']:
trend = "📈" if metric['change_percent'] > 0 else "📉"
print(f"\n{metric['name']} {trend}")
print(f"  Current: {metric['current']}")
print(f"  Change: {metric['change_percent']:+.1f}%")

return analytics
except Exception as e:
print(f"Error fetching analytics: {str(e)}")

if __name__ == "__main__":
get_analytics()

In Go:

func getAnalytics(client *searchfit.Client) {
ctx := context.Background()

analytics, err := client.Analytics.GetPerformanceMetrics(ctx, &searchfit.AnalyticsOptions{
TimeRange: "90d",
Metrics: []string{"citations", "visibility_score", "traffic_impact", "competitor_share"},
GroupBy: "engine",
})

if err != nil {
log.Fatalf("Error fetching analytics: %v", err)
}

fmt.Println("Performance Metrics (Last 90 Days):")
for _, metric := range analytics.Metrics {
trend := "📈"
if metric.ChangePercent < 0 {
trend = "📉"
}
fmt.Printf("\n%s %s\n", metric.Name, trend)
fmt.Printf("  Current: %v\n", metric.Current)
fmt.Printf("  Change: %+.1f%%\n", metric.ChangePercent)
}
}

These analytics queries give you visibility into how your content is performing across AI search engines. You'll see which engines are citing you most, where you're gaining traction, and where competitors are outperforming you.

Building Content Recommendations

One of SearchFit's most powerful features is its ability to recommend content that's optimized for AI search. The SDK provides endpoints that analyze top-performing queries and suggest content angles.

In Node.js:

const client = require('./auth');

async function getContentRecommendations() {
try {
const recommendations = await client.content.getRecommendations({
engines: ['perplexity', 'chatgpt', 'gemini'],
topicArea: 'your-industry',
contentType: 'blog-post',
aiVisibilityGap: true, // Focus on gaps where you're losing to competitors
});

console.log('AEO Content Recommendations:');
recommendations.forEach((rec) => {
console.log(`\nTopic: ${rec.topic}`);
console.log(`Recommended Angle: ${rec.angle}`);
console.log(`Search Volume (AI Engines): ${rec.estimatedQueries}`);
console.log(`Current Competitor Dominance: ${rec.competitorShare}%`);
console.log(`Opportunity Score: ${rec.opportunityScore}/100`);
console.log(`Suggested Content Structure:`);
rec.suggestedSections.forEach((section) => {
console.log(`  - ${section}`);
});
});
} catch (error) {
console.error('Error fetching recommendations:', error);
}
}

getContentRecommendations();

In Python:

from auth import client

def get_content_recommendations():
try:
recommendations = client.content.get_recommendations(
engines=['perplexity', 'chatgpt', 'gemini'],
topic_area='your-industry',
content_type='blog-post',
ai_visibility_gap=True
)

print("AEO Content Recommendations:")
print("=" * 50)

for rec in recommendations:
print(f"\nTopic: {rec['topic']}")
print(f"Recommended Angle: {rec['angle']}")
print(f"Search Volume (AI Engines): {rec['estimated_queries']}")
print(f"Opportunity Score: {rec['opportunity_score']}/100")
print(f"Suggested Content Structure:")
for section in rec['suggested_sections']:
print(f"  • {section}")

return recommendations
except Exception as e:
print(f"Error fetching recommendations: {str(e)}")

if __name__ == "__main__":
get_content_recommendations()

In Go:

func getContentRecommendations(client *searchfit.Client) {
ctx := context.Background()

recommendations, err := client.Content.GetRecommendations(ctx, &searchfit.RecommendationOptions{
Engines: []string{"perplexity", "chatgpt", "gemini"},
TopicArea: "your-industry",
ContentType: "blog-post",
AIVisibilityGap: true,
})

if err != nil {
log.Fatalf("Error fetching recommendations: %v", err)
}

fmt.Println("AEO Content Recommendations:")
for _, rec := range recommendations {
fmt.Printf("\nTopic: %s\n", rec.Topic)
fmt.Printf("Recommended Angle: %s\n", rec.Angle)
fmt.Printf("Search Volume: %d\n", rec.EstimatedQueries)
fmt.Printf("Opportunity Score: %d/100\n", rec.OpportunityScore)
fmt.Println("Suggested Content Structure:")
for _, section := range rec.SuggestedSections {
fmt.Printf("  • %s\n", section)
}
}
}

These recommendations bridge the gap between data and action. Instead of just knowing you're losing visibility to competitors on Perplexity, you get specific content ideas to reclaim that market share.

Error Handling and Best Practices

Production systems need robust error handling. The SearchFit SDK can encounter various errors, invalid credentials, rate limiting, network timeouts, and malformed requests. Here's how to handle them properly in each language.

Node.js error handling:

const client = require('./auth');

async function robustTracking() {
try {
const visibility = await client.tracking.getBrandVisibility({
engines: ['chatgpt', 'perplexity'],
timeRange: '30d',
});
return visibility;
} catch (error) {
if (error.code === 'AUTHENTICATION_ERROR') {
console.error('Invalid API credentials. Check your .env file.');
process.exit(1);
} else if (error.code === 'RATE_LIMIT_EXCEEDED') {
console.error('Rate limit exceeded. Waiting 60 seconds before retrying...');
await new Promise(resolve => setTimeout(resolve, 60000));
return robustTracking(); // Retry
} else if (error.code === 'NETWORK_ERROR') {
console.error('Network error. Check your internet connection.');
throw error;
} else {
console.error('Unexpected error:', error.message);
throw error;
}
}
}

robustTracking().catch(err => console.error('Final error:', err));

Python error handling:

from auth import client
import time
from searchfit.exceptions import (
AuthenticationError,
RateLimitError,
NetworkError,
SearchFitException
)

def robust_tracking(max_retries=3):
retries = 0
while retries < max_retries:
try:
visibility = client.tracking.get_brand_visibility(
engines=['chatgpt', 'perplexity'],
time_range='30d'
)
return visibility
except AuthenticationError:
print("Invalid API credentials. Check your .env file.")
exit(1)
except RateLimitError:
retries += 1
if retries < max_retries:
wait_time = 60 * retries  # Exponential backoff
print(f"Rate limited. Waiting {wait_time} seconds...")
time.sleep(wait_time)
else:
print("Max retries exceeded. Aborting.")
raise
except NetworkError:
print("Network error. Check your internet connection.")
raise
except SearchFitException as e:
print(f"SearchFit error: {str(e)}")
raise

if __name__ == "__main__":
try:
data = robust_tracking()
print("Data retrieved successfully")
except Exception as e:
print(f"Failed to retrieve data: {str(e)}")

Go error handling:

func robustTracking(client *searchfit.Client) error {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

visibility, err := client.Tracking.GetBrandVisibility(ctx, &searchfit.VisibilityOptions{
Engines: []string{"chatgpt", "perplexity"},
TimeRange: "30d",
})

if err != nil {
switch {
case errors.Is(err, searchfit.ErrAuthentication):
log.Fatal("Invalid API credentials. Check your environment variables.")
case errors.Is(err, searchfit.ErrRateLimit):
log.Println("Rate limited. Waiting before retry...")
time.Sleep(60 * time.Second)
return robustTracking(client) // Retry
case errors.Is(err, searchfit.ErrNetwork):
log.Printf("Network error: %v", err)
return err
case errors.Is(err, context.DeadlineExceeded):
log.Println("Request timeout. The API took too long to respond.")
return err
default:
log.Printf("Unexpected error: %v", err)
return err
}
}

fmt.Printf("Visibility data retrieved: %+v\n", visibility)
return nil
}

These patterns ensure your applications handle errors gracefully and don't crash unexpectedly. Exponential backoff (waiting longer between retries) is especially important for rate limiting.

Monitoring Your AEO Performance Over Time

Tracking visibility once is useful. Tracking it continuously is transformative. Let's build a monitoring system that runs on a schedule and alerts you to changes.

Node.js scheduled monitoring:

const cron = require('node-cron');
const client = require('./auth');
const fs = require('fs');
const path = require('path');

const logFile = path.join(__dirname, 'visibility-log.json');

async function monitorVisibility() {
try {
const visibility = await client.tracking.getBrandVisibility({
engines: ['chatgpt', 'perplexity', 'gemini', 'claude', 'grok'],
timeRange: '7d',
});

const timestamp = new Date().toISOString();
const record = { timestamp, visibility };

// Append to log file
let log = [];
if (fs.existsSync(logFile)) {
log = JSON.parse(fs.readFileSync(logFile, 'utf-8'));
}
log.push(record);
fs.writeFileSync(logFile, JSON.stringify(log, null, 2));

// Check for significant changes
if (log.length > 1) {
const previous = log[log.length - 2].visibility;
const current = log[log.length - 1].visibility;

visibility.engines.forEach((engine) => {
const prevEngine = previous.engines.find(e => e.name === engine.name);
if (prevEngine) {
const change = engine.citationCount - prevEngine.citationCount;
if (Math.abs(change) > 10) {
console.log(`⚠️  ${engine.name}: Citations changed by ${change > 0 ? '+' : ''}${change}`);
}
}
});
}

console.log(`✅ Visibility check completed at ${timestamp}`);
} catch (error) {
console.error(`❌ Monitoring error: ${error.message}`);
}
}

// Run every 6 hours
cron.schedule('0 */6 * * *', monitorVisibility);

console.log('AEO monitoring started. Running every 6 hours.');

Python scheduled monitoring:

import schedule
import time
import json
from datetime import datetime
from pathlib import Path
from auth import client

log_file = Path('visibility-log.json')

def monitor_visibility():
try:
visibility = client.tracking.get_brand_visibility(
engines=['chatgpt', 'perplexity', 'gemini', 'claude', 'grok'],
time_range='7d'
)

timestamp = datetime.now().isoformat()
record = {'timestamp': timestamp, 'visibility': visibility}

# Append to log
log = []
if log_file.exists():
with open(log_file, 'r') as f:
log = json.load(f)
log.append(record)

with open(log_file, 'w') as f:
json.dump(log, f, indent=2)

# Check for significant changes
if len(log) > 1:
previous = log[-2]['visibility']
current = log[-1]['visibility']

for engine in current['engines']:
prev_engine = next((e for e in previous['engines'] if e['name'] == engine['name']), None)
if prev_engine:
change = engine['citation_count'] - prev_engine['citation_count']
if abs(change) > 10:
print(f"⚠️  {engine['name']}: Citations changed by {change:+d}")

print(f"✅ Visibility check completed at {timestamp}")
except Exception as e:
print(f"❌ Monitoring error: {str(e)}")

def job():
monitor_visibility()

if __name__ == "__main__":
schedule.every(6).hours.do(job)
print("AEO monitoring started. Running every 6 hours.")

while True:
schedule.run_pending()
time.sleep(60)

Go scheduled monitoring:

package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"time"
"github.com/robfig/cron/v3"
)

type VisibilityRecord struct {
Timestamp  time.Time       `json:"timestamp"`
Visibility interface{}     `json:"visibility"`
}

func monitorVisibility(client *searchfit.Client) {
ctx := context.Background()

visibility, err := client.Tracking.GetBrandVisibility(ctx, &searchfit.VisibilityOptions{
Engines:   []string{"chatgpt", "perplexity", "gemini", "claude", "grok"},
TimeRange: "7d",
})

if err != nil {
log.Printf("❌ Monitoring error: %v", err)
return
}

// Read existing log
var log []VisibilityRecord
data, _ := ioutil.ReadFile("visibility-log.json")
if len(data) > 0 {
json.Unmarshal(data, &log)
}

// Append new record
record := VisibilityRecord{
Timestamp:  time.Now(),
Visibility: visibility,
}
log = append(log, record)

// Write back to file
logData, _ := json.MarshalIndent(log, "", "  ")
ioutil.WriteFile("visibility-log.json", logData, 0644)

fmt.Printf("✅ Visibility check completed at %s\n", time.Now().Format(time.RFC3339))
}

func main() {
client := getSearchFitClient()

c := cron.New()
c.AddFunc("0 */6 * * *", func() {
monitorVisibility(client)
})
c.Start()

fmt.Println("AEO monitoring started. Running every 6 hours.")
select {} // Keep running
}

Scheduled monitoring gives you a historical record of your AEO performance. Over time, you'll see trends, which engines are gaining importance, where your visibility is improving, and where you need to focus content efforts.

Integration with Your Existing Systems

Most teams don't want AEO data isolated in a separate tool. You'll want to integrate SearchFit visibility data into your existing dashboards, analytics platforms, and reporting systems.

Integrating with Google Sheets (Node.js example):

const { GoogleSpreadsheet } = require('google-spreadsheet');
const client = require('./auth');

async function pushToGoogleSheets() {
const doc = new GoogleSpreadsheet(process.env.GOOGLE_SHEET_ID);
await doc.useServiceAccountAuth({
client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
private_key: process.env.GOOGLE_PRIVATE_KEY,
});
await doc.loadInfo();

const sheet = doc.sheetsByTitle['SearchFit Visibility'];
const visibility = await client.tracking.getBrandVisibility({
engines: ['chatgpt', 'perplexity', 'gemini'],
timeRange: '30d',
});

for (const engine of visibility.engines) {
await sheet.addRow({
Date: new Date().toLocaleDateString(),
Engine: engine.name,
Citations: engine.citationCount,
'Visibility Score': engine.visibilityScore,
});
}

console.log('Data pushed to Google Sheets');
}

pushToGoogleSheets();

Integrating with Slack (Python example):

from auth import client
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

slack_client = WebClient(token=os.getenv('SLACK_BOT_TOKEN'))

def send_visibility_alert():
try:
visibility = client.tracking.get_brand_visibility(
engines=['chatgpt', 'perplexity', 'gemini'],
time_range='7d'
)

message = "📊 Weekly AEO Visibility Report\n\n"
for engine in visibility['engines']:
message += f"*{engine['name'].upper()}*\n"
message += f"Citations: {engine['citation_count']}\n"
message += f"Score: {engine['visibility_score']}/100\n\n"

slack_client.chat_postMessage(
channel="#marketing",
text=message
)
print("Alert sent to Slack")
except SlackApiError as e:
print(f"Slack error: {e}")

if __name__ == "__main__":
send_visibility_alert()

Integrating with your data warehouse (Go example):

func pushToDataWarehouse(client *searchfit.Client) {
ctx := context.Background()

visibility, err := client.Tracking.GetBrandVisibility(ctx, &searchfit.VisibilityOptions{
Engines:   []string{"chatgpt", "perplexity", "gemini"},
TimeRange: "30d",
})

if err != nil {
log.Fatalf("Error fetching visibility: %v", err)
}

// Connect to your data warehouse (BigQuery, Snowflake, etc.)
// This example uses BigQuery
client := bigquery.NewClient(ctx)
defer client.Close()

dataset := client.Dataset("searchfit_data")
table := dataset.Table("visibility_metrics")

for _, engine := range visibility.Engines {
row := &VisibilityRow{
Timestamp:       time.Now(),
Engine:          engine.Name,
Citations:       engine.CitationCount,
VisibilityScore: engine.VisibilityScore,
}

inserter := table.Inserter()
if err := inserter.Put(ctx, row); err != nil {
log.Printf("Error inserting row: %v", err)
}
}

fmt.Println("Data pushed to data warehouse")
}

Integrating SearchFit data into your existing systems ensures everyone on your team has access to AEO insights. Marketing leaders see it in dashboards, content teams see it in their workflows, and executives see it in reports.

Troubleshooting Common Issues

Even with proper setup, you might encounter issues. Here are the most common problems and how to fix them.

Authentication failures: The most common cause is incorrect or expired API keys. Double-check that your .env file is in the project root, that it's not committed to version control, and that your API key is current. You can regenerate your API key in the SearchFit dashboard.

Rate limiting: SearchFit enforces rate limits to protect its infrastructure. If you're hitting limits, implement exponential backoff (wait longer between retries) and consider batching requests. For high-volume operations, contact SearchFit support about higher rate limits.

Timeout errors: Network issues or slow responses can cause timeouts. Increase your timeout threshold (Node.js: timeout: 30000, Python: timeout=30, Go: context.WithTimeout(context.Background(), 30*time.Second)). If timeouts persist, check your internet connection and SearchFit's status page.

Empty results: If you're getting empty visibility data, you might be querying engines that haven't indexed your content yet, or your brand keywords might not be tracked. Check the SearchFit tracking dashboard to verify your tracked keywords and ensure they're relevant to your business.

SDK version conflicts: Make sure you're using compatible versions of the SDK and its dependencies. Update your SDK regularly: npm update searchfit (Node.js), pip install --upgrade searchfit (Python), go get -u github.com/searchfit/go-sdk (Go).

Key Takeaways and Next Steps

You now have a complete understanding of how to integrate the SearchFit SDK into Node.js, Python, and Go applications. Here's what you've learned:

Installation and authentication are straightforward across all three languages. Use environment variables to store your API credentials securely.

Tracking visibility across ChatGPT, Perplexity, Gemini, Claude, and other AI engines is the core value of SearchFit. The SDK makes it easy to fetch this data programmatically.

Analytics and recommendations go beyond raw visibility numbers. You get insights into which content angles are winning, where competitors are outperforming you, and what to write next.

Error handling and monitoring are critical for production systems. Implement retry logic, exponential backoff, and scheduled checks to keep your AEO strategy on track.

Integration with existing systems multiplies the value of SearchFit data. Push it to Google Sheets, Slack, your data warehouse, or your internal dashboards.

Your next steps depend on your situation. If you're an SEO lead, start tracking your brand visibility across AI engines today. If you're an engineer, pick one of the code examples above and integrate it into your monitoring system. If you're managing multiple clients or brands, use the concurrent patterns (especially Go's goroutines) to fetch data efficiently at scale.

The shift to AI search is happening now. Brands that wait to optimize for ChatGPT, Perplexity, and Gemini will find themselves losing organic traffic to competitors who move first. The SearchFit SDK gives you the tools to track, measure, and optimize your AEO strategy programmatically. Use it.

Get SearchFIT Weekly

What we are learning about getting brands cited in AI search, in your inbox every week. Unsubscribe any time.