Documentation Index
Fetch the complete documentation index at: https://docs.thena.ai/llms.txt
Use this file to discover all available pages before exploring further.
Organization events are published when organization-level changes occur, such as organization creation, updates, or member management. These events are delivered through the platform events system.
Developer quickstart
Minimal handler (organization only)
app.post("/webhook/platform-events", async (req, res) => {
const event = req.body;
if (!event?.eventId || !event?.eventType?.startsWith("organization:")) {
return res.status(200).send("OK");
}
res.status(200).send("OK");
switch (event.eventType) {
case "organization:created":
await onOrganizationCreated(event.payload.organization);
break;
case "organization:member-joined":
await onMemberJoined(event.payload.organization, event.payload.user);
break;
default:
break;
}
});
Checklist
- Enforce idempotency with
eventId to avoid creating duplicate resources.
- For plan/domain changes, re-sync dependent services (billing, DNS, SSO).
- For member events, respect role/permission propagation delays.
Event types
Organization lifecycle events
organization:created
Triggered when a new organization is created.
Payload structure:
{
organization: {
id: string;
name: string;
domain?: string;
subdomain: string;
plan: string;
status: string;
settings?: Record<string, unknown>;
metadata?: Record<string, unknown>;
createdAt: Date;
updatedAt: Date;
};
}
Event context:
- Triggered during organization setup process
- May be part of a larger user onboarding flow
- Often followed by initial configuration events
organization:updated
Triggered when an organization’s details are updated.
Payload structure:
{
organization: OrganizationData;
previousOrganization: OrganizationData; // Previous state before update
}
Common update scenarios:
- Plan changes (free to paid, plan upgrades/downgrades)
- Organization name or domain changes
- Settings updates (timezone, locale, etc.)
- Metadata modifications
organization:deleted
Triggered when an organization is deleted.
Payload structure:
{
previousOrganization: OrganizationData; // The deleted organization data
}
Important notes:
- This is a destructive operation
- All associated data (tickets, accounts, users) are also affected
- Consider implementing appropriate cleanup logic
Organization membership events
organization:member-joined
Triggered when a user joins an organization.
Payload structure:
{
organization: {
id: string;
name: string;
domain?: string;
subdomain: string;
plan: string;
status: string;
settings?: Record<string, unknown>;
createdAt: Date;
updatedAt: Date;
};
user: {
id: string;
email: string;
name: string;
userType: string;
status: string;
roles?: string[];
teams?: Array<{
id: string;
name: string;
}>;
metadata?: Record<string, unknown>;
createdAt: Date;
updatedAt: Date;
};
}
Common scenarios:
- New employee onboarding
- Contractor or external user access
- User role changes that affect organization membership
- Bulk user imports
Event structure
All organization events follow the standard platform event structure:
interface OrganizationEventEnvelope<T> {
eventId: string;
eventType: string; // One of the OrganizationEvents enum values
timestamp: string;
orgId: string;
actor: {
id: string;
type: string; // Usually "ADMIN" or "OWNER"
email: string;
};
payload: T;
}
Special considerations
Organization creation flow
When an organization is created, it typically triggers a cascade of events:
organization:created - The organization itself is created
organization:member-joined - The organization creator becomes the first member
- Additional setup events (teams, initial configuration)
Actor context
For organization events, the actor field represents:
- Creation: The user creating the organization (may be a system user for automated processes)
- Updates: The admin or owner making changes
- Member join: The user being added or the admin adding them
- Deletion: The admin or owner performing the deletion
Integration examples
Organization provisioning
function handleOrganizationCreated(payload) {
const { organization } = payload;
// Provision external resources
provisionSlackWorkspace(organization);
createBillingAccount(organization);
setupInitialTeams(organization);
// Send welcome emails
sendOrganizationWelcomeEmail(organization);
// Initialize analytics tracking
trackOrganizationCreated({
orgId: organization.id,
plan: organization.plan,
domain: organization.domain,
});
}
Member onboarding
function handleMemberJoined(payload) {
const { organization, user } = payload;
// Send welcome email with organization context
sendUserWelcomeEmail(user, organization);
// Provision user in external systems
createSlackUser(user, organization);
updateCRMContact(user, organization);
// Set up user permissions
assignDefaultPermissions(user, organization);
// Track user growth metrics
trackUserJoined({
orgId: organization.id,
userId: user.id,
userType: user.userType,
});
}
Plan change handling
function handleOrganizationUpdated(payload) {
const { organization, previousOrganization } = payload;
// Check if plan changed
if (organization.plan !== previousOrganization.plan) {
handlePlanChange({
orgId: organization.id,
previousPlan: previousOrganization.plan,
newPlan: organization.plan,
});
// Update billing
updateBillingPlan(organization);
// Adjust feature access
updateFeatureAccess(organization);
}
// Check for domain changes
if (organization.domain !== previousOrganization.domain) {
updateDNSRecords(organization);
updateSSLCertificates(organization);
}
}
Organization cleanup
function handleOrganizationDeleted(payload) {
const { previousOrganization } = payload;
// Clean up external resources
deprovisionSlackWorkspace(previousOrganization);
cancelBillingSubscription(previousOrganization);
// Archive data in external systems
archiveAnalyticsData(previousOrganization.id);
archiveCRMData(previousOrganization.id);
// Send confirmation emails to admins
sendDeletionConfirmation(previousOrganization);
// Update metrics
trackOrganizationDeleted({
orgId: previousOrganization.id,
plan: previousOrganization.plan,
memberCount: previousOrganization.memberCount,
});
}
Security considerations
Sensitive data
Organization events may contain sensitive information:
- Billing details in plan changes
- Domain information that could reveal company structure
- User email addresses and roles
Access control
- Ensure subscribers have appropriate permissions
- Consider scoping subscriptions based on sensitivity levels
- Implement proper authentication for webhook endpoints
Monitoring and alerting
Key metrics to track
- Organization growth: Track creation and deletion rates
- Plan changes: Monitor upgrade/downgrade patterns
- Member growth: Track user addition rates per organization
- Churn indicators: Monitor organizations with recent plan downgrades
Alert scenarios
// High-value organization deletion
if (
organization.plan === "Enterprise" &&
eventType === "organization:deleted"
) {
alertSalesTeam(organization);
}
// Rapid member growth (potential abuse)
if (memberJoinedCount > 100 && timeWindow < "1 hour") {
alertSecurityTeam(organization);
}
// Plan downgrade after recent upgrade
if (planChangePattern === "upgrade_then_downgrade" && timeWindow < "7 days") {
alertCustomerSuccess(organization);
}
Best practices
- Event ordering: Process organization events before related entity events
- Idempotency: Use
eventId to prevent duplicate processing
- Cascading effects: Be prepared for organization events to trigger additional events
- Data consistency: Ensure external systems reflect organization state changes
- Performance: Organization events can trigger expensive operations, consider async processing
Error handling
Common error scenarios and handling strategies:
function handleOrganizationEventError(event, error) {
switch (error.type) {
case "EXTERNAL_SERVICE_UNAVAILABLE":
// Retry with exponential backoff
scheduleRetry(event, { delay: calculateBackoff(event.retryCount) });
break;
case "INVALID_ORGANIZATION_STATE":
// Log and alert, may require manual intervention
logCriticalError(event, error);
alertOperationsTeam(event, error);
break;
case "RATE_LIMIT_EXCEEDED":
// Queue for later processing
queueForLaterProcessing(event, { delay: "5 minutes" });
break;
default:
// Generic error handling
logError(event, error);
if (event.retryCount < MAX_RETRIES) {
scheduleRetry(event);
} else {
alertDevelopmentTeam(event, error);
}
}
}
Event frequency
Organization events are typically low-frequency events:
- Creation: Usually during initial setup or business growth
- Updates: Periodic configuration changes, plan modifications
- Member joins: Varies by organization size and growth phase
- Deletion: Rare, but critical for cleanup processes
However, during bulk operations or migrations, these events can spike significantly.