Platform Module

Complete API reference for sso.platform module - platform owner administration, organization management, user management, analytics, and audit logs

Updated Dec 16, 2025
Edit on GitHub

Platform Module

The platform module (sso.platform) provides administrative capabilities for platform owners. All methods require a Platform Owner JWT token.

Organization Tiers

sso.platform.getTiers()

Signature:

getTiers(): Promise<OrganizationTier[]>

Description: List all available organization tiers on the platform.

Parameters: None

Returns: Promise<OrganizationTier[]> - Array of organization tiers. Each tier includes:

  • id (string) - Unique tier ID
  • display_name (string) - Human-readable tier name
  • max_services (number | null) - Maximum number of services allowed (null = unlimited)
  • max_users (number | null) - Maximum number of users allowed (null = unlimited)
  • price_cents (number) - Monthly price in cents
  • created_at (string) - ISO 8601 timestamp when tier was created

Example:

const tiers = await sso.platform.getTiers();

tiers.forEach(tier => {
  console.log(`${tier.display_name}: $${tier.price_cents / 100}/mo`);
  console.log(`  Max Services: ${tier.max_services ?? 'Unlimited'}`);
  console.log(`  Max Users: ${tier.max_users ?? 'Unlimited'}`);
});

Throws:

  • 403 Forbidden - User is not a platform owner

Related:


Organization Management

The sso.platform.organizations namespace provides methods for managing organizations across the platform.

sso.platform.organizations.list()

Signature:

organizations.list(params?: ListPlatformOrganizationsParams): Promise<PlatformOrganizationsListResponse>

Description: List all organizations on the platform with optional filters and pagination.

Parameters:

Name Type Description
params ListPlatformOrganizationsParams (optional) Query parameters
params.status ‘pending’ | ‘active’ | ‘suspended’ | ‘rejected’ Filter by organization status
params.tier_id string Filter by tier ID
params.page number Page number (default: 1)
params.limit number Results per page (default: 20, max: 100)

Returns: Promise<PlatformOrganizationsListResponse> - Paginated list with:

  • organizations (Organization[]) - Array of organization objects
  • total (number) - Total number of organizations matching filters
  • page (number) - Current page number
  • limit (number) - Results per page

Example:

// List all pending organizations
const result = await sso.platform.organizations.list({
  status: 'pending',
  page: 1,
  limit: 50
});

console.log(`${result.total} pending organizations`);
result.organizations.forEach(org => {
  console.log(`- ${org.name} (${org.slug})`);
  console.log(`  Created: ${new Date(org.created_at).toLocaleDateString()}`);
});

// List organizations on a specific tier
const tierOrgs = await sso.platform.organizations.list({
  tier_id: 'tier-pro',
  page: 1,
  limit: 100
});
console.log(`${tierOrgs.total} organizations on Pro tier`);

Throws:

  • 403 Forbidden - User is not a platform owner
  • 400 Bad Request - Invalid query parameters

Related:


sso.platform.organizations.approve()

Signature:

organizations.approve(orgId: string, payload: ApproveOrganizationPayload): Promise<Organization>

Description: Approve a pending organization and assign it a tier. The organization owner will be notified and can begin using the platform.

Parameters:

Name Type Description
orgId string Organization ID
payload ApproveOrganizationPayload Approval details
payload.tier_id string Tier ID to assign to the organization

Returns: Promise<Organization> - The approved organization object

Example:

const approved = await sso.platform.organizations.approve('org-id-123', {
  tier_id: 'tier-starter'
});

console.log(` Approved ${approved.name}`);
console.log(`  Status: ${approved.status}`);
console.log(`  Tier: ${approved.tier_id}`);

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - Organization doesn’t exist
  • 400 Bad Request - Organization is not in pending status or invalid tier ID

Related:


sso.platform.organizations.reject()

Signature:

organizations.reject(orgId: string, payload: RejectOrganizationPayload): Promise<Organization>

Description: Reject a pending organization with a reason. The organization owner will be notified of the rejection.

Parameters:

Name Type Description
orgId string Organization ID
payload RejectOrganizationPayload Rejection details
payload.reason string Reason for rejection (shown to organization owner)

Returns: Promise<Organization> - The rejected organization object

Example:

await sso.platform.organizations.reject('org-id-123', {
  reason: 'Organization name violates platform terms of service'
});

console.log('Organization rejected');

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - Organization doesn’t exist
  • 400 Bad Request - Organization is not in pending status

Related:


sso.platform.organizations.suspend()

Signature:

organizations.suspend(orgId: string): Promise<Organization>

Description: Suspend an active organization. Suspended organizations cannot authenticate users or access the platform until reactivated.

Parameters:

Name Type Description
orgId string Organization ID

Returns: Promise<Organization> - The suspended organization object

Example:

const suspended = await sso.platform.organizations.suspend('org-id-123');

console.log(` Suspended ${suspended.name}`);
console.log(`  Status: ${suspended.status}`);

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - Organization doesn’t exist
  • 400 Bad Request - Organization is not in active status

Related:


sso.platform.organizations.activate()

Signature:

organizations.activate(orgId: string): Promise<Organization>

Description: Re-activate a suspended organization. The organization will regain full platform access.

Parameters:

Name Type Description
orgId string Organization ID

Returns: Promise<Organization> - The activated organization object

Example:

const activated = await sso.platform.organizations.activate('org-id-123');

console.log(` Activated ${activated.name}`);
console.log(`  Status: ${activated.status}`);

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - Organization doesn’t exist
  • 400 Bad Request - Organization is not in suspended status

Related:


sso.platform.organizations.updateTier()

Signature:

organizations.updateTier(orgId: string, payload: UpdateOrganizationTierPayload): Promise<Organization>

Description: Update an organization’s tier and resource limits. This allows you to upgrade/downgrade organizations or apply custom limits.

Parameters:

Name Type Description
orgId string Organization ID
payload UpdateOrganizationTierPayload Tier update details
payload.tier_id string New tier ID
payload.max_services number (optional) Override max services limit
payload.max_users number (optional) Override max users limit

Returns: Promise<Organization> - The updated organization object

Example:

// Upgrade organization to Pro tier
await sso.platform.organizations.updateTier('org-id-123', {
  tier_id: 'tier-pro'
});

// Apply custom limits (enterprise customer)
await sso.platform.organizations.updateTier('org-id-456', {
  tier_id: 'tier-enterprise',
  max_services: 100,
  max_users: 1000
});

console.log('Organization tier updated');

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - Organization or tier doesn’t exist
  • 400 Bad Request - Invalid tier ID or limits

Related:


sso.platform.organizations.delete()

Signature:

organizations.delete(orgId: string): Promise<{success: boolean, message: string}>

Description: Permanently delete an organization and all its associated data. This is a destructive operation that cannot be undone. All related data will be cascaded deleted including members, services, subscriptions, and audit logs.

Parameters:

Name Type Description
orgId string Organization ID

Returns: Promise<{success: boolean, message: string}> - Deletion confirmation

Example:

// WARNING: This is irreversible!
const result = await sso.platform.organizations.delete('org-id-123');

console.log(result.message); // 'Organization deleted successfully'

// Best practice: Confirm with user before deleting
const confirmDelete = confirm(
  `Are you sure you want to permanently delete this organization? This cannot be undone.`
);

if (confirmDelete) {
  await sso.platform.organizations.delete(orgId);
  console.log(' Organization deleted');
}

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - Organization doesn’t exist

Related:


Platform Owner Management

sso.platform.promoteOwner()

Signature:

promoteOwner(payload: PromotePlatformOwnerPayload): Promise<void>

Description: Promote an existing user to platform owner. Platform owners have full administrative access across the entire platform.

Parameters:

Name Type Description
payload PromotePlatformOwnerPayload Promotion details
payload.user_id string ID of the user to promote

Returns: Promise<void> - No return value on success

Example:

await sso.platform.promoteOwner({
  user_id: 'user-uuid-here'
});

console.log(' User promoted to platform owner');

Throws:

  • 403 Forbidden - Current user is not a platform owner
  • 404 Not Found - User doesn’t exist
  • 400 Bad Request - User is already a platform owner

Related:


sso.platform.demoteOwner()

Signature:

demoteOwner(userId: string): Promise<void>

Description: Demote a platform owner to regular user. The user will lose all platform administrative privileges.

Parameters:

Name Type Description
userId string ID of the platform owner to demote

Returns: Promise<void> - No return value on success

Example:

await sso.platform.demoteOwner('user-uuid-here');

console.log(' Platform owner demoted to regular user');

Throws:

  • 403 Forbidden - Current user is not a platform owner
  • 404 Not Found - User doesn’t exist
  • 400 Bad Request - User is not a platform owner or is the last platform owner

Related:


User Management

The sso.platform.users namespace provides methods for managing users across the platform.

sso.platform.users.search()

Signature:

users.search(query: string, options?: { limit?: number }): Promise<Array<UserSearchResult>>

Description: Search users by email address or user ID across the entire platform.

Parameters:

Name Type Description
query string Search query (email or user ID)
options object (optional) Search options
options.limit number Maximum results (default: 10, max: 50)

Returns: Promise<UserSearchResult[]> - Array of matching users. Each result includes:

  • id (string) - User ID
  • email (string) - User email
  • is_platform_owner (boolean) - Whether user is a platform owner
  • created_at (string) - ISO 8601 timestamp when user was created

Example:

// Search by email
const users = await sso.platform.users.search('john@example.com');
console.log(users); // [{ id: 'user-uuid', email: 'john@example.com', ... }]

// Search by partial email
const matches = await sso.platform.users.search('john@', { limit: 5 });
console.log(`Found ${matches.length} users matching 'john@'`);

// Search by user ID
const userById = await sso.platform.users.search('user-uuid-here');
if (userById.length > 0) {
  console.log(`Found user: ${userById[0].email}`);
}

Throws:

  • 403 Forbidden - User is not a platform owner
  • 400 Bad Request - Invalid query or limit

Related:


sso.platform.users.getMfaStatus()

Signature:

users.getMfaStatus(userId: string): Promise<{enabled: boolean, has_backup_codes: boolean}>

Description: Get MFA (Multi-Factor Authentication) status for a specific user.

Parameters:

Name Type Description
userId string User ID

Returns: Promise<{enabled: boolean, has_backup_codes: boolean}> - MFA status with:

  • enabled (boolean) - Whether MFA is enabled for the user
  • has_backup_codes (boolean) - Whether user has generated backup codes

Example:

const mfaStatus = await sso.platform.users.getMfaStatus('user-uuid-here');

if (mfaStatus.enabled) {
  console.log(' MFA is enabled for this user');
  console.log(`  Backup codes: ${mfaStatus.has_backup_codes ? 'Yes' : 'No'}`);
} else {
  console.log('MFA is not enabled for this user');
}

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - User doesn’t exist

Related:


sso.platform.users.forceDisableMfa()

Signature:

users.forceDisableMfa(userId: string): Promise<{success: boolean, message: string}>

Description: Force disable MFA for a user (emergency access). Use this when a user has lost access to their authenticator device and backup codes.

Parameters:

Name Type Description
userId string User ID

Returns: Promise<{success: boolean, message: string}> - Success confirmation

Example:

// User has lost their authenticator and backup codes
const result = await sso.platform.users.forceDisableMfa('user-uuid-here');

console.log(result.message); // 'MFA disabled successfully'
console.log(' User can now log in without MFA');

// Best practice: Verify user identity before disabling MFA
const mfaStatus = await sso.platform.users.getMfaStatus(userId);
if (mfaStatus.enabled) {
  const confirmed = confirm(
    'Are you sure you want to disable MFA for this user? They should re-enable it after regaining access.'
  );

  if (confirmed) {
    await sso.platform.users.forceDisableMfa(userId);
    console.log(' MFA disabled - user should re-enable ASAP');
  }
}

Throws:

  • 403 Forbidden - User is not a platform owner
  • 404 Not Found - User doesn’t exist
  • 400 Bad Request - MFA is not enabled for this user

Related:


Audit Logs

sso.platform.getAuditLog()

Signature:

getAuditLog(params?: GetAuditLogParams): Promise<AuditLogEntry[]>

Description: Retrieve the platform-wide audit log with optional filters. Audit logs track all administrative actions across the platform.

Parameters:

Name Type Description
params GetAuditLogParams (optional) Query parameters
params.action string Filter by specific action (e.g., ‘organization.approved’)
params.actor_id string Filter by user who performed the action
params.target_type string Filter by target type (e.g., ‘organization’, ‘user’)
params.target_id string Filter by specific target ID
params.start_date string Filter by start date (ISO 8601)
params.end_date string Filter by end date (ISO 8601)
params.limit number Maximum results (default: 100, max: 1000)

Returns: Promise<AuditLogEntry[]> - Array of audit log entries. Each entry includes:

  • id (string) - Unique log entry ID
  • action (string) - Action performed
  • actor_id (string) - ID of user who performed the action
  • actor_email (string) - Email of user who performed the action
  • target_type (string | null) - Type of target affected
  • target_id (string | null) - ID of target affected
  • metadata (object | null) - Additional action-specific data
  • created_at (string) - ISO 8601 timestamp when action occurred

Example:

// Get recent audit logs
const logs = await sso.platform.getAuditLog({
  limit: 100
});

logs.forEach(log => {
  console.log(`[${log.created_at}] ${log.actor_email}: ${log.action}`);
  if (log.metadata) {
    console.log(`  Details:`, log.metadata);
  }
});

// Filter by specific action
const approvals = await sso.platform.getAuditLog({
  action: 'organization.approved',
  start_date: '2024-01-01',
  limit: 50
});

console.log(`${approvals.length} organizations approved since Jan 1, 2024`);

// Track specific organization's history
const orgHistory = await sso.platform.getAuditLog({
  target_type: 'organization',
  target_id: 'org-id-123'
});

console.log(`Audit history for organization:`);
orgHistory.forEach(log => {
  console.log(`  - ${log.action} by ${log.actor_email} on ${log.created_at}`);
});

Throws:

  • 403 Forbidden - User is not a platform owner
  • 400 Bad Request - Invalid query parameters

Related:


Platform Analytics

The sso.platform.analytics namespace provides platform-wide metrics and insights.

sso.platform.analytics.getOverview()

Signature:

analytics.getOverview(): Promise<PlatformOverviewMetrics>

Description: Get platform overview metrics including total counts and recent activity.

Parameters: None

Returns: Promise<PlatformOverviewMetrics> - Overview metrics with:

  • total_organizations (number) - Total organizations on platform
  • active_organizations (number) - Organizations with active status
  • total_users (number) - Total users across all organizations
  • total_services (number) - Total services across all organizations
  • total_logins_30d (number) - Total logins in the last 30 days
  • unique_users_30d (number) - Unique users who logged in in last 30 days

Example:

const metrics = await sso.platform.analytics.getOverview();

console.log('Platform Overview:');
console.log(`  Organizations: ${metrics.active_organizations}/${metrics.total_organizations}`);
console.log(`  Total Users: ${metrics.total_users}`);
console.log(`  Total Services: ${metrics.total_services}`);
console.log(`  30-Day Activity:`);
console.log(`    - Logins: ${metrics.total_logins_30d}`);
console.log(`    - Active Users: ${metrics.unique_users_30d}`);

// Calculate engagement rate
const engagementRate = (metrics.unique_users_30d / metrics.total_users * 100).toFixed(1);
console.log(`    - Engagement Rate: ${engagementRate}%`);

Throws:

  • 403 Forbidden - User is not a platform owner

Related:


sso.platform.analytics.getOrganizationStatus()

Signature:

analytics.getOrganizationStatus(): Promise<OrganizationStatusBreakdown>

Description: Get organization count breakdown by status.

Parameters: None

Returns: Promise<OrganizationStatusBreakdown> - Status counts with:

  • pending (number) - Organizations awaiting approval
  • active (number) - Active organizations
  • suspended (number) - Suspended organizations
  • rejected (number) - Rejected organizations

Example:

const breakdown = await sso.platform.analytics.getOrganizationStatus();

console.log('Organization Status:');
console.log(`  � Pending: ${breakdown.pending}`);
console.log(`   Active: ${breakdown.active}`);
console.log(`  � Suspended: ${breakdown.suspended}`);
console.log(`   Rejected: ${breakdown.rejected}`);

// Alert if pending queue is high
if (breakdown.pending > 10) {
  console.warn(`� ${breakdown.pending} organizations awaiting approval`);
}

Throws:

  • 403 Forbidden - User is not a platform owner

Related:


sso.platform.analytics.getGrowthTrends()

Signature:

analytics.getGrowthTrends(params?: PlatformAnalyticsDateRangeParams): Promise<GrowthTrendPoint[]>

Description: Get platform growth trends over time (organizations and users).

Parameters:

Name Type Description
params PlatformAnalyticsDateRangeParams (optional) Date range
params.start_date string Start date (ISO 8601, default: 30 days ago)
params.end_date string End date (ISO 8601, default: today)

Returns: Promise<GrowthTrendPoint[]> - Array of growth data points. Each point includes:

  • date (string) - Date (YYYY-MM-DD)
  • total_organizations (number) - Cumulative organizations on this date
  • new_organizations (number) - New organizations created on this date
  • total_users (number) - Cumulative users on this date
  • new_users (number) - New users created on this date

Example:

// Get 30-day growth trends
const trends = await sso.platform.analytics.getGrowthTrends({
  start_date: '2024-01-01',
  end_date: '2024-01-31'
});

console.log('Growth Trends (Jan 2024):');
trends.forEach(point => {
  console.log(`${point.date}:`);
  console.log(`  Organizations: ${point.total_organizations} (+${point.new_organizations})`);
  console.log(`  Users: ${point.total_users} (+${point.new_users})`);
});

// Calculate growth rate
const firstDay = trends[0];
const lastDay = trends[trends.length - 1];
const orgGrowth = ((lastDay.total_organizations - firstDay.total_organizations) / firstDay.total_organizations * 100).toFixed(1);
console.log(`\nOrganization growth: ${orgGrowth}%`);

Throws:

  • 403 Forbidden - User is not a platform owner
  • 400 Bad Request - Invalid date range

Related:


sso.platform.analytics.getLoginActivity()

Signature:

analytics.getLoginActivity(params?: PlatformAnalyticsDateRangeParams): Promise<LoginActivityPoint[]>

Description: Get platform-wide login activity trends over time.

Parameters:

Name Type Description
params PlatformAnalyticsDateRangeParams (optional) Date range
params.start_date string Start date (ISO 8601, default: 30 days ago)
params.end_date string End date (ISO 8601, default: today)

Returns: Promise<LoginActivityPoint[]> - Array of login activity data points. Each point includes:

  • date (string) - Date (YYYY-MM-DD)
  • total_logins (number) - Total logins on this date
  • unique_users (number) - Unique users who logged in on this date
  • failed_logins (number) - Failed login attempts on this date

Example:

// Get 7-day login activity
const activity = await sso.platform.analytics.getLoginActivity({
  start_date: '2024-01-01',
  end_date: '2024-01-07'
});

console.log('Login Activity (Jan 1-7):');
activity.forEach(point => {
  console.log(`${point.date}:`);
  console.log(`  Logins: ${point.total_logins}`);
  console.log(`  Unique Users: ${point.unique_users}`);
  console.log(`  Failed Attempts: ${point.failed_logins}`);

  // Calculate failure rate
  const failureRate = (point.failed_logins / (point.total_logins + point.failed_logins) * 100).toFixed(1);
  console.log(`  Failure Rate: ${failureRate}%`);
});

// Identify peak login days
const peakDay = activity.reduce((max, point) =>
  point.total_logins > max.total_logins ? point : max
);
console.log(`\nPeak day: ${peakDay.date} with ${peakDay.total_logins} logins`);

Throws:

  • 403 Forbidden - User is not a platform owner
  • 400 Bad Request - Invalid date range

Related:


sso.platform.analytics.getTopOrganizations()

Signature:

analytics.getTopOrganizations(): Promise<TopOrganization[]>

Description: Get top organizations by activity (most active in the last 30 days).

Parameters: None

Returns: Promise<TopOrganization[]> - Array of top organizations (limited to top 10). Each organization includes:

  • id (string) - Organization ID
  • name (string) - Organization name
  • slug (string) - Organization slug
  • user_count (number) - Total users in organization
  • service_count (number) - Total services in organization
  • login_count_30d (number) - Logins in last 30 days
  • unique_users_30d (number) - Unique users who logged in in last 30 days

Example:

const topOrgs = await sso.platform.analytics.getTopOrganizations();

console.log('Top 10 Most Active Organizations (30 days):');
topOrgs.forEach((org, index) => {
  console.log(`${index + 1}. ${org.name} (${org.slug})`);
  console.log(`   Users: ${org.user_count} | Services: ${org.service_count}`);
  console.log(`   Logins: ${org.login_count_30d} (${org.unique_users_30d} unique users)`);

  // Calculate engagement
  const engagement = (org.unique_users_30d / org.user_count * 100).toFixed(1);
  console.log(`   Engagement: ${engagement}%`);
});

Throws:

  • 403 Forbidden - User is not a platform owner

Related:


sso.platform.analytics.getRecentOrganizations()

Signature:

analytics.getRecentOrganizations(params?: GetAuditLogParams): Promise<RecentOrganization[]>

Description: Get recently created organizations.

Parameters:

Name Type Description
params GetAuditLogParams (optional) Query parameters
params.limit number Maximum results (default: 10)

Returns: Promise<RecentOrganization[]> - Array of recent organizations. Each organization includes:

  • id (string) - Organization ID
  • name (string) - Organization name
  • slug (string) - Organization slug
  • status (string) - Organization status
  • tier_id (string | null) - Assigned tier ID
  • created_at (string) - ISO 8601 timestamp when created

Example:

// Get 10 most recent organizations
const recent = await sso.platform.analytics.getRecentOrganizations({
  limit: 10
});

console.log('Recently Created Organizations:');
recent.forEach(org => {
  const daysAgo = Math.floor((Date.now() - new Date(org.created_at).getTime()) / (1000 * 60 * 60 * 24));
  console.log(`- ${org.name} (${org.slug})`);
  console.log(`  Status: ${org.status} | Created: ${daysAgo} days ago`);
});

// Count by status
const pending = recent.filter(org => org.status === 'pending').length;
console.log(`\n${pending} awaiting approval`);

Throws:

  • 403 Forbidden - User is not a platform owner

Related:


Complete Example: Platform Administration Dashboard

Here’s a complete example showing how to build a platform administration dashboard:

import { SsoClient } from '@drmhse/sso-sdk';

const sso = new SsoClient({
  baseURL: 'https://authos.example.com',
  token: localStorage.getItem('sso_access_token')
});

async function displayPlatformDashboard() {
  console.log('=== PLATFORM ADMINISTRATION DASHBOARD ===\n');

  // 1. Platform Overview
  const overview = await sso.platform.analytics.getOverview();
  console.log('PLATFORM OVERVIEW:');
  console.log(`  Total Organizations: ${overview.total_organizations}`);
  console.log(`  Active Organizations: ${overview.active_organizations}`);
  console.log(`  Total Users: ${overview.total_users}`);
  console.log(`  Total Services: ${overview.total_services}`);
  console.log(`  30-Day Logins: ${overview.total_logins_30d}`);
  console.log(`  30-Day Active Users: ${overview.unique_users_30d}`);

  // 2. Organization Status Breakdown
  const status = await sso.platform.analytics.getOrganizationStatus();
  console.log('\nORGANIZATION STATUS:');
  console.log(`  � Pending: ${status.pending}`);
  console.log(`   Active: ${status.active}`);
  console.log(`  � Suspended: ${status.suspended}`);
  console.log(`   Rejected: ${status.rejected}`);

  // 3. Pending Organizations (need approval)
  if (status.pending > 0) {
    const pendingOrgs = await sso.platform.organizations.list({
      status: 'pending',
      limit: 10
    });

    console.log('\nORGANIZATIONS AWAITING APPROVAL:');
    pendingOrgs.organizations.forEach(org => {
      console.log(`  - ${org.name} (${org.slug})`);
      console.log(`    Owner: ${org.owner_email}`);
      console.log(`    Created: ${new Date(org.created_at).toLocaleDateString()}`);
    });
  }

  // 4. Top Organizations
  const topOrgs = await sso.platform.analytics.getTopOrganizations();
  console.log('\nTOP 5 MOST ACTIVE ORGANIZATIONS:');
  topOrgs.slice(0, 5).forEach((org, index) => {
    console.log(`  ${index + 1}. ${org.name}`);
    console.log(`     Logins (30d): ${org.login_count_30d}`);
    console.log(`     Active Users: ${org.unique_users_30d}/${org.user_count}`);
  });

  // 5. Recent Activity
  const recent = await sso.platform.analytics.getRecentOrganizations({ limit: 5 });
  console.log('\nRECENTLY CREATED ORGANIZATIONS:');
  recent.forEach(org => {
    const daysAgo = Math.floor((Date.now() - new Date(org.created_at).getTime()) / (1000 * 60 * 60 * 24));
    console.log(`  - ${org.name} (${daysAgo} days ago) - Status: ${org.status}`);
  });

  // 6. Audit Log Summary
  const auditLogs = await sso.platform.getAuditLog({ limit: 10 });
  console.log('\nRECENT ADMINISTRATIVE ACTIONS:');
  auditLogs.forEach(log => {
    console.log(`  [${new Date(log.created_at).toLocaleString()}]`);
    console.log(`  ${log.actor_email}: ${log.action}`);
  });
}

// Run the dashboard
displayPlatformDashboard();

Best Practices

  1. Access Control: Platform owner endpoints are extremely powerful. Ensure only trusted administrators have platform owner access.

  2. Audit Everything: Always check audit logs before making major changes (suspensions, deletions) to understand the organization’s history.

  3. Tier Management: Use tiers to control resource limits and pricing. Apply custom limits for enterprise customers.

  4. User Support: Use forceDisableMfa() sparingly and only after verifying user identity through alternative channels.

  5. Analytics Review: Regularly review platform analytics to identify trends, issues, and growth opportunities.

  6. Organization Lifecycle:

    • Review pending organizations promptly
    • Provide clear rejection reasons
    • Suspend before deleting (gives organizations a chance to resolve issues)
    • Only delete organizations as a last resort
  7. Search Before Action: Always use users.search() to verify user identity before performing administrative actions.

Type Definitions

PlatformOrganizationResponse

interface PlatformOrganizationResponse {
  id: string;
  slug: string;
  name: string;
  owner_user_id: string;
  status: OrganizationStatus;
  tier_id: string;
  max_services?: number | null;
  max_users?: number | null;
  approved_by?: string | null;
  approved_at?: string | null;
  rejected_by?: string | null;
  rejected_at?: string | null;
  rejection_reason?: string | null;
  created_at: string;
  updated_at: string;
  tier: OrganizationTier;
  owner: User;
}

ApproveOrganizationPayload

interface ApproveOrganizationPayload {
  tier_id: string;
}

RejectOrganizationPayload

interface RejectOrganizationPayload {
  reason: string;
}

UpdateOrganizationTierPayload

interface UpdateOrganizationTierPayload {
  tier_id: string;
  max_services?: number;
  max_users?: number;
}

PromotePlatformOwnerPayload

interface PromotePlatformOwnerPayload {
  user_id: string;
}

AuditLogEntry

interface AuditLogEntry {
  id: string;
  user_id: string;
  user_email: string;
  action: string;
  resource_type: string;
  resource_id: string;
  details?: Record<string, any>;
  ip_address?: string;
  user_agent?: string;
  created_at: string;
}

ListPlatformOrganizationsParams

interface ListPlatformOrganizationsParams {
  page?: number;
  limit?: number;
  status?: OrganizationStatus;
  search?: string;
  tier_id?: string;
}

GetAuditLogParams

interface GetAuditLogParams {
  page?: number;
  limit?: number;
  user_id?: string;
  action?: string;
  resource_type?: string;
  start_date?: string;
  end_date?: string;
}

PlatformOverviewMetrics

interface PlatformOverviewMetrics {
  total_organizations: number;
  total_users: number;
  total_end_users: number;
  total_services: number;
  total_logins_24h: number;
  total_logins_30d: number;
}

OrganizationStatusBreakdown

interface OrganizationStatusBreakdown {
  pending: number;
  active: number;
  suspended: number;
  rejected: number;
}

GrowthTrendPoint

interface GrowthTrendPoint {
  date: string;
  new_organizations: number;
  new_users: number;
}

LoginActivityPoint

interface LoginActivityPoint {
  date: string;
  count: number;
}

TopOrganization

interface TopOrganization {
  id: string;
  name: string;
  slug: string;
  user_count: number;
  service_count: number;
  login_count_30d: number;
}

RecentOrganization

interface RecentOrganization {
  id: string;
  name: string;
  slug: string;
  status: OrganizationStatus;
  created_at: string;
}

OrganizationStatus

type OrganizationStatus = 'pending' | 'active' | 'suspended' | 'rejected';