> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paygentic.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Source Installation Management

> Monitor integration health, troubleshoot issues, and automate customer success workflows with the Source Installation API.

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

1. **Active**: Integration working properly, data flowing
2. **Disconnected**: Customer manually disconnected or credentials expired
3. **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:

```javascript theme={null}
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:

```javascript theme={null}
// 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:

```javascript theme={null}
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:

```javascript theme={null}
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:

<AccordionGroup>
  <Accordion title="Invalid Credentials">
    **Symptoms**: `status: "error"`, `errorMessage: "Invalid API key"`

    **Resolution**:

    ```javascript theme={null}
    // 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');
    }
    ```
  </Accordion>

  <Accordion title="Expired OAuth Token">
    **Symptoms**: `status: "error"`, `errorMessage: "Token expired"`

    **Resolution**:

    ```javascript theme={null}
    // 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');
    }
    ```
  </Accordion>

  <Accordion title="Stripe Account Issues">
    **Symptoms**: `status: "error"`, `errorMessage: "Account access denied"`

    **Resolution**:

    ```javascript theme={null}
    // 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');
    }
    ```
  </Accordion>
</AccordionGroup>

## 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

1. Guide customer to reconnect the source from their subscription portal.

## API reference

### List installations

```http theme={null}
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

```http theme={null}
GET /sources/{sourceId}/installations/{installationId}
```

Returns detailed installation information including error messages, sync timestamps, and configuration.

### Update installation

```http theme={null}
PATCH /sources/{sourceId}/installations/{installationId}
```

**Request Body:**

```json theme={null}
{
  "status": "active|disconnected|error",
  "config": {},
  "metadata": {},
  "errorMessage": "Error description"
}
```

<Info>
  Most installation management should be done through the UI. The API is primarily for monitoring, diagnostics, and automation workflows.
</Info>

## Next steps

* **[Usage Events →](/platform/billing/usage-events)** - Understanding how source data becomes billable usage
* **[API Reference →](/api-reference)** - Complete API documentation
