Code Examples

Complete Sync Flow Example (Python)

  import requests
  import json
  from datetime import datetime

  class ZluriSDKClient:
      def __init__(self, api_key):
          self.api_key = api_key
          self.base_url = "https://api-ext.zluri.com"
          self.headers = {
              "api-key": f"{api_key}",
              "Content-Type": "application/json"
          }

      def create_instance(self, app_id, instance_name, notification_emails=None):
          """Step 2: Create Instance"""
          data = {
              "app_id": app_id,
              "instance_name": instance_name
          }
          if notification_emails:
              data["notification_emails"] = notification_emails

          response = requests.post(
              f"{self.base_url}/v2/integrations-sync/instances",
              json=data,
              headers=self.headers
          )
          response.raise_for_status()
          return response.json()["data"]["instance_id"]

      def init_sync(self, instance_id):
          """Step 3: Initialize Sync"""
          response = requests.post(
              f"{self.base_url}/v2/integrations-sync/instances/{instance_id}/syncs",
              headers=self.headers
          )
          response.raise_for_status()
          return response.json()["sync_id"]

      def upload_snapshot_data(self, sync_id, entity_name, data, page_number=1):
          """Step 4: Upload Data Chunks"""
          upload_data = {
              "entity_name": entity_name,
              "page_number": page_number,
              "data": data
          }

          response = requests.post(
              f"{self.base_url}/v2/integrations-sync/syncs/{sync_id}/snapshot-data",
              json=upload_data,
              headers=self.headers
          )
          response.raise_for_status()
          return response.json()

      def finish_sync(self, sync_id):
          """Step 5: Finish Sync"""
          response = requests.put(
              f"{self.base_url}/v2/integrations-sync/syncs/{sync_id}/finish",
              headers=self.headers
          )
          response.raise_for_status()
          return response.json()

      def check_sync_status(self, sync_id):
          """Step 6: Check Processing Status"""
          response = requests.get(
              f"{self.base_url}/ext/integrations/sync-sdk/v2/syncs/{sync_id}",
              headers=self.headers
          )
          response.raise_for_status()
          return response.json()

      def sync_users(self, instance_id, users_data):
          """Complete flow to sync users"""
          try:
              # Step 3: Initialize sync
              sync_id = self.init_sync(instance_id)
              print(f"✓ Sync initiated: {sync_id}")

              # Step 4: Upload data in chunks
              chunk_size = 1000
              for i in range(0, len(users_data), chunk_size):
                  chunk = users_data[i:i+chunk_size]
                  page_number = (i // chunk_size) + 1

                  result = self.upload_snapshot_data(
                      sync_id,
                      "users",
                      chunk,
                      page_number
                  )
                  print(f"✓ Uploaded page {page_number}: {result['totalRecordsUploaded']} records")

              # Step 5: Finish sync
              finish_result = self.finish_sync(sync_id)
              print(f"✓ Sync completed: {finish_result['message']}")

              # Step 6: Check status
              status = self.check_sync_status(sync_id)
              print(f"✓ Current status: {status['status']}")

              return sync_id

          except requests.exceptions.RequestException as e:
              print(f"✗ Error during sync: {e}")
              if hasattr(e.response, 'json'):
                  print(f"✗ Error details: {e.response.json()}")
              raise

  # Example usage
  if __name__ == "__main__":
      # Step 1: API Key (already obtained from dashboard)
      client = ZluriSDKClient("YOUR_API_KEY")

      # Sample user data - covers every attribute of the users entity
      # Required: work_email, unique_id. All other fields are optional.
      users = [
          {
              # Identity
              "unique_id": "usr_10001",
              "work_email": "[email protected]",
              "personal_email": "[email protected]",
              "alternate_emails": ["[email protected]", "[email protected]"],
              "name": "John Doe",
              "first_name": "John",
              "last_name": "Doe",
              "user_name": "john.doe",
              "profile_picture": "https://cdn.company.com/avatars/john.png",

              # Organisation
              "department": "Engineering",
              "job_title": "Software Engineer",
              "reporting_manager_email": "[email protected]",
              "business_unit": "Product and Technology",
              "cost_center": "Research and Development",
              "cost_center_code": "CC-1001",
              "location": "Bengaluru, India",
              "employee_type": "Full-time",

              # Lifecycle (ISO 8601 date-time)
              "date_of_joining": "2023-04-01T00:00:00Z",
              "date_of_termination": None,
              "created_at": "2023-04-01T09:30:00Z",
              "modified_at": datetime.utcnow().isoformat() + "Z",
              "last_login": "2026-09-23T14:05:12Z",

              # Access - status is one of: active, inactive, suspended, None
              "status": "active",
              "roles": ["Admin", "Developer"],
              "license_names": ["Enterprise", "Premium Support"],

              # Custom fields - up to 100 keys; values are string, number, boolean or None
              "custom_fields": {
                  "employee_id": "EMP-4521",
                  "grade": "L3",
                  "is_contractor": False,
                  "seat_count": 1
              }
          }
      ]

      # Execute the sync flow
      instance_id = "YOUR_INSTANCE_ID"  # From Step 2
      sync_id = client.sync_users(instance_id, users)

Node.js Example

const axios = require('axios');

class ZluriSDKClient {
    constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://api-ext.zluri.com';
        this.headers = {
            'api-key': apiKey,
            'Content-Type': 'application/json'
        };
    }

    async createInstance(appId, instanceName, notificationEmails = null) {
        /**
         * Step 2: Create Instance
         */
        const data = {
            app_id: appId,
            instance_name: instanceName
        };

        if (notificationEmails) {
            data.notification_emails = notificationEmails;
        }

        try {
            const response = await axios.post(
                `${this.baseUrl}/v2/integrations-sync/instances`,
                data,
                { headers: this.headers }
            );
            return response.data.data.instance_id;
        } catch (error) {
            throw error;
        }
    }

    async initSync(instanceId) {
        /**
         * Step 3: Initialize Sync
         */
        try {
            const response = await axios.post(
                `${this.baseUrl}/v2/integrations-sync/instances/${instanceId}/syncs`,
                {},
                { headers: this.headers }
            );
            return response.data.sync_id;
        } catch (error) {
            throw error;
        }
    }

    async uploadSnapshotData(syncId, entityName, data, pageNumber = 1) {
        /**
         * Step 4: Upload Data Chunks
         */
        const uploadData = {
            entity_name: entityName,
            page_number: pageNumber,
            data: data
        };

        try {
            const response = await axios.post(
                `${this.baseUrl}/v2/integrations-sync/syncs/${syncId}/snapshot-data`,
                uploadData,
                { headers: this.headers }
            );
            return response.data;
        } catch (error) {
            throw error;
        }
    }

    async finishSync(syncId) {
        /**
         * Step 5: Finish Sync
         */
        try {
            const response = await axios.put(
                `${this.baseUrl}/v2/integrations-sync/syncs/${syncId}/finish`,
                {},
                { headers: this.headers }
            );
            return response.data;
        } catch (error) {
            throw error;
        }
    }

    async checkSyncStatus(syncId) {
        /**
         * Step 6: Check Processing Status
         */
        try {
            const response = await axios.get(
                `${this.baseUrl}/ext/integrations/sync-sdk/v2/syncs/${syncId}`,
                { headers: this.headers }
            );
            return response.data;
        } catch (error) {
            throw error;
        }
    }

    async syncUsers(instanceId, usersData) {
        /**
         * Complete flow to sync users
         */
        try {
            // Step 3: Initialize sync
            const syncId = await this.initSync(instanceId);
            console.log(`✓ Sync initiated: ${syncId}`);

            // Step 4: Upload data in chunks
            const chunkSize = 1000;
            for (let i = 0; i < usersData.length; i += chunkSize) {
                const chunk = usersData.slice(i, i + chunkSize);
                const pageNumber = Math.floor(i / chunkSize) + 1;

                const result = await this.uploadSnapshotData(
                    syncId,
                    'users',
                    chunk,
                    pageNumber
                );
                console.log(`✓ Uploaded page ${pageNumber}: ${result.totalRecordsUploaded} records`);
            }

            // Step 5: Finish sync
            const finishResult = await this.finishSync(syncId);
            console.log(`✓ Sync completed: ${finishResult.message}`);

            // Step 6: Check status
            const status = await this.checkSyncStatus(syncId);
            console.log(`✓ Current status: ${status.status}`);

            return syncId;

        } catch (error) {
            console.error(`✗ Error during sync: ${error.message}`);
            if (error.response && error.response.data) {
                console.error(`✗ Error details:`, error.response.data);
            }
            throw error;
        }
    }
}

// Example usage
async function main() {
    // Step 1: API Key (already obtained from dashboard)
    const client = new ZluriSDKClient('YOUR_API_KEY');

    // Sample user data - covers every attribute of the users entity
    // Required: work_email, unique_id. All other fields are optional.
    const users = [
        {
            // Identity
            unique_id: 'usr_10001',
            work_email: '[email protected]',
            personal_email: '[email protected]',
            alternate_emails: ['[email protected]', '[email protected]'],
            name: 'John Doe',
            first_name: 'John',
            last_name: 'Doe',
            user_name: 'john.doe',
            profile_picture: 'https://cdn.company.com/avatars/john.png',

            // Organisation
            department: 'Engineering',
            job_title: 'Software Engineer',
            reporting_manager_email: '[email protected]',
            business_unit: 'Product and Technology',
            cost_center: 'Research and Development',
            cost_center_code: 'CC-1001',
            location: 'Bengaluru, India',
            employee_type: 'Full-time',

            // Lifecycle (ISO 8601 date-time)
            date_of_joining: '2023-04-01T00:00:00Z',
            date_of_termination: null,
            created_at: '2023-04-01T09:30:00Z',
            modified_at: new Date().toISOString(),
            last_login: '2026-09-23T14:05:12Z',

            // Access - status is one of: active, inactive, suspended, null
            status: 'active',
            roles: ['Admin', 'Developer'],
            license_names: ['Enterprise', 'Premium Support'],

            // Custom fields - up to 100 keys; values are string, number, boolean or null
            custom_fields: {
                employee_id: 'EMP-4521',
                grade: 'L3',
                is_contractor: false,
                seat_count: 1
            }
        }
    ];

    try {
        // Execute the sync flow
        const instanceId = 'YOUR_INSTANCE_ID'; // From Step 2
        const syncId = await client.syncUsers(instanceId, users);
        console.log(`Sync completed with ID: ${syncId}`);
    } catch (error) {
        console.error('Sync failed:', error.message);
    }
}

// Run example if this file is executed directly
if (require.main === module) {
    main();
}

module.exports = ZluriSDKClient;