Source installations represent the individual connections between your data sources and customer subscriptions. While most installation management happens through the UI, the API provides powerful capabilities for monitoring integration health, diagnosing issues, and building automation workflows.
Core Concepts
Installation vs Source
Source : The template configuration (what data to collect, how to process it)
Installation : The live connection between a source and a specific customer subscription
Installation Lifecycle
Active : Integration working properly, data flowing
Disconnected : Customer manually disconnected or credentials expired
Error : Technical failure, invalid credentials, or API issues
Provider Types
Ampersand : Most common, handles OAuth flows and webhook management
OAuth : Direct OAuth integrations (Coming Soon)
API Key : Simple credential-based connections (Coming Soon)
Health Monitoring
Monitor your customers’ integration health programmatically to catch issues before they impact revenue tracking.
Check Single Customer Status
Monitor a specific customer’s integration:
const response = await fetch (
`https://api.paygentic.io/v0/sources/ ${ sourceId } /installations?subscriptionId= ${ customerId } ` ,
{
headers: {
'Authorization' : `Bearer ${ process . env . PAYGENTIC_API_KEY } `
}
}
);
const { data : installations } = await response . json ();
const installation = installations [ 0 ];
if ( ! installation ) {
console . log ( '❌ Customer has not connected their integration' );
} else if ( installation . status !== 'active' ) {
console . log ( '⚠️ Integration issue:' , installation . errorMessage );
console . log ( 'Last sync:' , installation . lastSyncAt );
} else {
console . log ( '✅ Integration healthy' );
}
Find Problematic Integrations
Identify customers whose integrations need attention:
// Get all disconnected integrations
const disconnected = await fetch (
`https://api.paygentic.io/v0/sources/ ${ sourceId } /installations?status=disconnected` ,
{
headers: { 'Authorization' : `Bearer ${ apiKey } ` }
}
);
// Get integrations with errors
const errors = await fetch (
`https://api.paygentic.io/v0/sources/ ${ sourceId } /installations?status=error` ,
{
headers: { 'Authorization' : `Bearer ${ apiKey } ` }
}
);
console . log ( ` ${ disconnected . data . length } customers disconnected` );
console . log ( ` ${ errors . data . length } customers have errors` );
Build Health Dashboard
Get an overview of all customer integrations:
const response = await fetch (
`https://api.paygentic.io/v0/sources/ ${ sourceId } /installations?limit=100` ,
{
headers: { 'Authorization' : `Bearer ${ apiKey } ` }
}
);
const installations = await response . json ();
const healthStats = {
total: installations . data . length ,
active: installations . data . filter ( i => i . status === 'active' ). length ,
disconnected: installations . data . filter ( i => i . status === 'disconnected' ). length ,
errors: installations . data . filter ( i => i . status === 'error' ). length
};
console . log ( 'Integration Health:' , healthStats );
// Output: { total: 47, active: 42, disconnected: 3, errors: 2 }
Troubleshooting Workflows
When customers report “revenue not tracking,” use these diagnostic patterns to quickly identify and resolve issues.
”Revenue Not Tracking” Diagnostics
Step-by-step diagnostic workflow:
async function diagnoseRevenueIssue ( sourceId , customerId ) {
// Step 1: Find customer's installation
const installations = await fetch (
`https://api.paygentic.io/v0/sources/ ${ sourceId } /installations?subscriptionId= ${ customerId } `
);
const installation = installations . data [ 0 ];
if ( ! installation ) {
return {
issue: 'NO_INSTALLATION' ,
action: 'Customer needs to connect their Stripe account' ,
resolution: 'Send them the authorization link'
};
}
// Step 2: Check installation status
const detailedInstallation = await fetch (
`https://api.paygentic.io/v0/sources/ ${ sourceId } /installations/ ${ installation . id } `
);
const details = await detailedInstallation . json ();
if ( details . status === 'disconnected' ) {
return {
issue: 'DISCONNECTED' ,
action: 'Customer disconnected their integration' ,
resolution: 'Guide them through reconnection process' ,
disconnectedAt: details . disconnectedAt
};
}
if ( details . status === 'error' ) {
return {
issue: 'INTEGRATION_ERROR' ,
action: 'Technical error occurred' ,
resolution: 'Check error message and guide reconnection' ,
error: details . errorMessage ,
lastWorking: details . lastSyncAt
};
}
// Step 3: Check recent data flow
const hoursSinceSync = details . lastSyncAt
? ( Date . now () - new Date ( details . lastSyncAt )) / ( 1000 * 60 * 60 )
: null ;
if ( ! details . lastSyncAt || hoursSinceSync > 48 ) {
return {
issue: 'NO_RECENT_DATA' ,
action: 'No recent data received' ,
resolution: 'Check if customer has recent Stripe activity' ,
lastSync: details . lastSyncAt
};
}
return {
issue: 'UNKNOWN' ,
action: 'Installation appears healthy' ,
resolution: 'Check source events and processing status'
};
}
// Usage
const diagnosis = await diagnoseRevenueIssue ( 'src_123' , 'sub_456' );
console . log ( diagnosis );
Connection Failure Patterns
Common failure scenarios and their indicators:
Symptoms : status: "error"
, errorMessage: "Invalid API key"
Resolution :// Customer needs to update their Stripe API key
const installation = await getInstallation ( sourceId , installationId );
if ( installation . errorMessage ?. includes ( 'Invalid API key' )) {
// Guide customer to generate new API key
console . log ( 'Customer needs to update Stripe credentials' );
}
Symptoms : status: "error"
, errorMessage: "Token expired"
Resolution :// OAuth token needs refresh
const installation = await getInstallation ( sourceId , installationId );
if ( installation . errorMessage ?. includes ( 'Token expired' )) {
// Trigger OAuth reconnection flow
console . log ( 'Customer needs to re-authorize OAuth connection' );
}
Symptoms : status: "error"
, errorMessage: "Account access denied"
Resolution :// Stripe account restrictions or permissions
const installation = await getInstallation ( sourceId , installationId );
if ( installation . errorMessage ?. includes ( 'Account access' )) {
console . log ( 'Check Stripe account status and permissions' );
}
Error Reference
Common Status Codes
Status Description Action Required active
Integration working properly None disconnected
Customer manually disconnected Guide reconnection error
Technical failure occurred Check error message, troubleshoot
Recovery Procedures
For Credential Issues
Guide customer to reconnect the source from their subscription portal.
API Reference
List Installations
GET /sources/{sourceId}/installations
Query Parameters:
subscriptionId
(optional) - Filter by customer subscription
status
(optional) - Filter by status: active
, disconnected
, error
limit
(optional) - Number of results (max 100, default 50)
offset
(optional) - Pagination offset (default 0)
Get Installation Details
GET /sources/{sourceId}/installations/{installationId}
Returns detailed installation information including error messages, sync timestamps, and configuration.
Update Installation
PATCH /sources/{sourceId}/installations/{installationId}
Request Body:
{
"status" : "active|disconnected|error" ,
"config" : {},
"metadata" : {},
"errorMessage" : "Error description"
}
Most installation management should be done through the UI. The API is primarily for monitoring, diagnostics, and automation workflows.
Next Steps