# Addigy API Integration Guide This guide explains how to use the Addigy API integration in the PSA-Utils application. ## Setup ### 1. Get Your Addigy API Token 1. Log into your Addigy account 2. Navigate to **Account > Integrations** 3. Click on the **V2** tab under "Addigy API" 4. Click **New API Token** 5. Enter a name for your token (e.g., "PSA-Utils Integration") 6. Select the appropriate permissions: - **View Devices** - Required to fetch device information - **View Policies** - Required to fetch policy information - **View Organizations** - Optional, for organization data - Additional permissions as needed for your use case 7. Click **Save** 8. **Copy the API token immediately** - you won't be able to see it again! **Note**: The Addigy v2 API uses the `x-api-key` header for authentication, not Bearer tokens. ### 2. Configure Environment Variables Add your Addigy API token to `.env.local`: ```bash # Addigy API Configuration ADDIGY_API_URL=https://api.addigy.com/api/v2 ADDIGY_API_TOKEN=your_actual_token_here # Optional: Parent Organization ID (if needed) # ADDIGY_ORG_ID=your_org_id_here ``` ### 3. Restart Your Development Server After updating the `.env.local` file, restart your Next.js development server: ```bash npm run dev ``` ## Usage ### Import the Addigy Client ```typescript import { getAddigyClient } from '@/lib/services/addigy-factory'; const addigyClient = getAddigyClient(); ``` ### Common Operations #### Get All Devices ```typescript const devices = await addigyClient.getAllDevices(); console.log(`Found ${devices.length} devices`); ``` #### Get Online Devices Only ```typescript const onlineDevices = await addigyClient.getOnlineDevices(); ``` #### Get Devices by Policy ```typescript const policyId = '003f01fa-9bb3-421a-be29-409adf7a1xxx'; const devices = await addigyClient.getDevicesByPolicy(policyId); ``` #### Get Device Applications ```typescript const deviceId = '114x11c3-b5dy-4n38-92fb-34th6ju782se'; const applications = await addigyClient.getDeviceApplications(deviceId); ``` #### Get All Policies ```typescript const policies = await addigyClient.getAllPolicies(); ``` #### Get Policy by ID ```typescript const policyId = '76yh84t0-ju74-bh45-jd6b-ok87y4gc83gt'; const policy = await addigyClient.getPolicyById(policyId); ``` #### Get Active Alerts ```typescript const alerts = await addigyClient.getActiveAlerts(); ``` #### Get Maintenance Items ```typescript const maintenanceItems = await addigyClient.getMaintenanceItems(); ``` #### Get Custom Facts for a Device ```typescript const deviceId = '114x11c3-b5dy-4n38-92fb-34th6ju782se'; const facts = await addigyClient.getCustomFacts(deviceId); ``` #### Assign Device to Policy ```typescript const deviceId = '114x11c3-b5dy-4n38-92fb-34th6ju782se'; const newPolicyId = '76yh84t0-ju74-bh45-jd6b-ok87y4gc83gt'; await addigyClient.assignDeviceToPolicy(deviceId, newPolicyId); ``` ### Advanced Queries with Filters ```typescript // Get devices with custom filters const devices = await addigyClient.getAllDevices({ filters: [ { audit_field: 'Free Disk Percentage', type: 'number', operation: 'less_than', value: 20, }, { audit_field: 'Firewall Enabled', type: 'boolean', operation: 'equals', value: false, }, ], limit: 100, page: 1, }); ``` ### Pagination for Large Datasets ```typescript // Get all devices with automatic pagination const allDevices = await addigyClient.getAllDevicesPaginated(100); console.log(`Total devices: ${allDevices.length}`); ``` ### Test Connection ```typescript const isConnected = await addigyClient.testConnection(); if (isConnected) { console.log('Successfully connected to Addigy API'); } else { console.error('Failed to connect to Addigy API'); } ``` ## API Endpoints The integration includes the following pre-built API endpoints: ### GET `/api/addigy-devices` Fetch devices from Addigy. Automatically retrieves the organization ID from policies if not configured. **Query Parameters:** - `policyId` (optional) - Filter devices by policy ID - `online` (optional) - Set to 'true' to get only online devices **Example:** ```bash # Get all devices curl http://localhost:3000/api/addigy-devices # Get devices for a specific policy curl http://localhost:3000/api/addigy-devices?policyId=76yh84t0-ju74-bh45-jd6b-ok87y4gc83gt # Get only online devices curl http://localhost:3000/api/addigy-devices?online=true ``` ### GET `/api/addigy-policies` Fetch all policies from Addigy. ## Important API Details ### Authentication - Uses `x-api-key` header (not `Authorization: Bearer`) - Single API token for authentication ### Endpoint Structure - **Devices**: `POST /o/{orgid}/devices` - Requires organization ID - **Policies**: `POST /oa/policies/query` - Returns flat array - All endpoints use POST with JSON body, not GET ### Request Body Format ```json { "page": 1, "per_page": 500, "query": { "filters": [...] } } ``` ### Response Structure #### Devices Response Devices are returned with nested `facts` structure: ```json { "items": [ { "facts": { "device_name": { "value": "MacBook-Pro", "type": "string" }, "serial_number": { "value": "C02XX...", "type": "string" }, "online": { "value": true, "type": "boolean" } } } ] } ``` #### Policies Response Policies return as a flat array: ```json [ { "policyId": "69ae51e4-...", "orgid": "4200f347-...", "name": "Policy Name" } ] ``` **Example:** ```bash curl http://localhost:3000/api/addigy-policies ``` ## Rate Limiting The Addigy API has a rate limit of **1,000 requests per 10 seconds**. The client includes built-in rate limiting to prevent exceeding this limit. If you exceed the rate limit, further requests will be rejected for 24 hours. ## Type Definitions All Addigy types are defined in `/lib/types/addigy.ts`. Key types include: - `AddigyDevice` - Device information - `AddigyPolicy` - Policy information - `AddigyApplication` - Installed application details - `AddigyAlert` - Alert information - `AddigyOrganization` - Organization details - `AddigyMaintenanceItem` - Maintenance task information - `AddigyMonitoringItem` - Monitoring rule information - `AddigyCustomFact` - Custom facts/variables - `AddigySoftwareItem` - Software catalog items ## Error Handling Always wrap API calls in try-catch blocks: ```typescript try { const devices = await addigyClient.getAllDevices(); // Process devices } catch (error) { console.error('Error fetching devices:', error); // Handle error appropriately } ``` ## Common Device Fields Addigy returns device fields in snake_case format. The integration automatically maps these to Title Case for UI compatibility: | Addigy Field | Mapped To | Description | |--------------|-----------|-------------| | `agentid` | `agentid` | Unique device identifier | | `device_name` | `Device Name` | Device hostname | | `device_model_name` | `Device Model Name` | Device model (e.g., "MacBook Pro") | | `mac_os_x_version` | `MAC OS X Version` | macOS version | | `ios_version` | `iOS Version` | iOS version | | `online` | `online` | Boolean indicating if device is online | | `policy_id` | `policy_id` | Current policy ID | | `current_user` | `Current User` | Currently logged in user | | `serial_number` | `Serial Number` | Device serial number | | `free_disk_percentage` | `Free Disk Percentage` | Available disk space percentage | | `battery_percentage` | `Battery Percentage` | Current battery level | | `firewall_enabled` | `Firewall Enabled` | Boolean | | `filevault_enabled` | `FileVault Enabled` | Boolean | | `agent_version` | `Agent Version` | Addigy agent version | ## Resources - [Addigy API v2 Documentation](https://support.addigy.com/hc/en-us/articles/16938210315411-API-Documentation-v2) - [Addigy API v2 Interactive Docs](https://api.addigy.com/api/v2/documentation/) - [Addigy Support Center](https://support.addigy.com/) ## Troubleshooting ### "ADDIGY_API_TOKEN environment variable is required" Make sure you've added your API token to the `.env.local` file and restarted your development server. ### "API Error: Unauthorized" or 401 Error Check that your API token is valid and has the necessary permissions. You may need to create a new token with the correct permissions in Addigy. ### "404 page not found" Error This usually means: 1. Wrong endpoint path - check you're using `/o/{orgid}/devices` for devices 2. Missing organization ID - the integration will auto-fetch from policies if not configured 3. Using GET instead of POST - all Addigy v2 endpoints require POST ### Empty Device Names Addigy uses snake_case field names (e.g., `device_name`). The integration automatically maps these to the UI-expected format (e.g., `Device Name`). ### Rate Limit Exceeded If you receive a rate limit error, wait 24 hours before making more API requests. Consider implementing caching or reducing the frequency of API calls. ### "Invalid JSON response from Addigy API" This may indicate an issue with the API endpoint or your token permissions. Check the Addigy API documentation for the specific endpoint you're trying to access. ## Next Steps - Explore the Addigy API documentation for additional endpoints - Create custom API routes for your specific use cases - Integrate Addigy data with your Autotask or other systems - Build dashboards to visualize device status, alerts, and compliance