Customer Users
Code Examples
Practical examples for working with customer users
Complete API Client
JavaScript/Node.js
const axios = require('axios')
class CustomerUsersAPI {
constructor(keyId, keySecret) {
this.credentials = { keyId, keySecret }
this.baseURL = 'https://api.performchat.com/rest/v1'
}
async list(filters = {}, page = 1, limit = 20) {
const response = await axios.get(`${this.baseURL}/customer-users`, {
params: { page, limit },
data: {
...this.credentials,
...filters
}
})
return response.data
}
async findByEmail(email) {
const result = await this.list({ email }, 1, 1)
return result.data[0] || null
}
async findByExternalId(externalId) {
const result = await this.list({ external_id: externalId }, 1, 1)
return result.data[0] || null
}
async update(userId, updates) {
const response = await axios.put(
`${this.baseURL}/customer-users/${userId}`,
{
...this.credentials,
...updates
}
)
return response.data
}
async syncUser(externalId, userData) {
const existing = await this.findByExternalId(externalId)
if (existing) {
return await this.update(existing.id, userData)
}
// User will be created on first token generation
return null
}
}
// Usage
const api = new CustomerUsersAPI(
process.env.API_KEY_ID,
process.env.API_KEY_SECRET
)
const user = await api.findByEmail('user@example.com')
if (user) {
await api.update(user.id, {
metadata: { plan: 'premium' }
})
}Python
import os
import requests
from typing import Optional, Dict, List
class CustomerUsersAPI:
def __init__(self, key_id: str, key_secret: str):
self.credentials = {
"keyId": key_id,
"keySecret": key_secret
}
self.base_url = "https://api.performchat.com/rest/v1"
def list(
self,
filters: Optional[Dict] = None,
page: int = 1,
limit: int = 20
) -> Dict:
data = {**self.credentials, **(filters or {})}
response = requests.get(
f"{self.base_url}/customer-users",
params={"page": page, "limit": limit},
json=data
)
response.raise_for_status()
return response.json()
def find_by_email(self, email: str) -> Optional[Dict]:
result = self.list({"email": email}, page=1, limit=1)
return result['data'][0] if result['data'] else None
def find_by_external_id(self, external_id: str) -> Optional[Dict]:
result = self.list({"external_id": external_id}, page=1, limit=1)
return result['data'][0] if result['data'] else None
def update(self, user_id: str, updates: Dict) -> Dict:
response = requests.put(
f"{self.base_url}/customer-users/{user_id}",
json={**self.credentials, **updates}
)
response.raise_for_status()
return response.json()
def sync_user(self, external_id: str, user_data: Dict) -> Optional[Dict]:
existing = self.find_by_external_id(external_id)
if existing:
return self.update(existing['id'], user_data)
return None
# Usage
api = CustomerUsersAPI(
os.getenv("API_KEY_ID"),
os.getenv("API_KEY_SECRET")
)
user = api.find_by_email("user@example.com")
if user:
api.update(user['id'], {
"metadata": {"plan": "premium"}
})Common Use Cases
User Synchronization Webhook
// Webhook handler for user updates in your system
app.post('/webhooks/user-updated', async (req, res) => {
const { userId, name, email, plan } = req.body
try {
await api.syncUser(userId, {
name,
email,
metadata: {
plan,
sync_date: new Date().toISOString()
}
})
res.json({ success: true })
} catch (error) {
console.error('Sync failed:', error)
res.status(500).json({ error: 'Sync failed' })
}
})Export All Users
async function exportAllUsers() {
const allUsers = []
let page = 1
let hasMore = true
while (hasMore) {
const result = await api.list({}, page, 100)
allUsers.push(...result.data)
hasMore = page < result.pagination.total_pages
page++
}
return allUsers
}
// Export to CSV
async function exportToCSV() {
const users = await exportAllUsers()
const csv = [
['ID', 'External ID', 'Name', 'Email', 'Active', 'Created'].join(','),
...users.map(u =>
[u.id, u.external_id, `"${u.name}"`, u.email, u.active, u.created_at].join(',')
)
].join('\n')
return csv
}User Activity Dashboard
async function getUserActivityStats() {
const users = await exportAllUsers()
const now = new Date()
const oneDayAgo = new Date(now - 24 * 60 * 60 * 1000)
const oneWeekAgo = new Date(now - 7 * 24 * 60 * 60 * 1000)
return {
total: users.length,
active: users.filter(u => u.active).length,
lastDay: users.filter(u =>
new Date(u.last_seen_at) > oneDayAgo
).length,
lastWeek: users.filter(u =>
new Date(u.last_seen_at) > oneWeekAgo
).length
}
}Bulk Metadata Update
async function bulkUpdatePlan(externalIds, newPlan) {
const results = []
for (const externalId of externalIds) {
try {
const user = await api.findByExternalId(externalId)
if (user) {
const updated = await api.update(user.id, {
metadata: {
...user.metadata,
plan: newPlan
}
})
results.push({ externalId, success: true, user: updated })
} else {
results.push({ externalId, success: false, error: 'User not found' })
}
} catch (error) {
results.push({ externalId, success: false, error: error.message })
}
}
return results
}
// Usage
const results = await bulkUpdatePlan(
['user_1', 'user_2', 'user_3'],
'enterprise'
)Error Handling
async function safeUpdateUser(userId, updates) {
try {
return await api.update(userId, updates)
} catch (error) {
if (error.response?.status === 404) {
console.error(`User ${userId} not found`)
return null
} else if (error.response?.status === 401) {
throw new Error('Invalid API credentials')
} else {
console.error('Update failed:', error.message)
throw error
}
}
}Related Pages
- List Users - API reference for listing users
- Update User - API reference for updating users
- Token Generation - Generate tokens for users