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;