Documentation Index Fetch the complete documentation index at: https://docs.vortexsoftware.com/llms.txt
Use this file to discover all available pages before exploring further.
Vortex handles the complete invitation lifecycle — sending invites via email/SMS/share links, tracking clicks and conversions, managing referral programs, and optimizing your invitation flows with A/B testing. You focus on your product; Vortex handles the growth mechanics.
Installation
npm install @teamvortexsoftware/vortex-node-22-sdk
Quick Start
Generate a secure token for Vortex components
import { Vortex } from '@teamvortexsoftware/vortex-node-22-sdk' ;
const vortex = new Vortex ( process . env . VORTEX_API_KEY ! );
// Generate a token for the current user
const token = vortex . generateToken ({
user: { id: 'user-123' , email: 'user@example.com' }
});
// Pass the token to your frontend component
// <VortexInvite token={token} />
Integration Flow
Vortex uses a split architecture: your backend signs tokens with the SDK, and your frontend renders components that use those tokens to securely interact with Vortex.
Install the backend SDK
Add this SDK to your Node.js server npm install @ teamvortexsoftware / vortex - node - 22 - sdk
Initialize the client
Create a Vortex client with your API key (keep this on the server!) import { Vortex } from '@teamvortexsoftware/vortex-node-22-sdk' ;
const vortex = new Vortex ( process . env . VORTEX_API_KEY );
Generate a token for the current user
When a user loads a page with a Vortex component, generate a signed token on your server const token = vortex . generateToken ({ user: { id: currentUser . id } });
Pass the token to your frontend
Include the token in your page response or API response res . json ({ vortexToken: token , ... otherData });
Render a Vortex component with the token
Use the React/Angular/Web Component with the token import { VortexInvite } from '@teamvortexsoftware/vortex-react' ;
< VortexInvite token = { vortexToken } />
Vortex handles the rest
The component securely communicates with Vortex servers, displays the invitation UI, sends emails/SMS, tracks conversions, and reports analytics
Methods
Core Methods
generateToken()
Sign a payload for use with Vortex widgets
This method generates a signed JWT token containing your payload data.
The token can be passed to widgets via the token prop to authenticate
and authorize the request.
generateToken(payload: GenerateTokenData, options?: GenerateTokenOptions | undefined): string
Parameters:
Name Type Required Description payloadGenerateTokenData✓ Data to sign (user, component, scope, vars, etc.) options`GenerateTokenOptions undefined` Optional configuration (expiresIn)
Returns: string — Signed JWT token string
// --- Backend (Node.js/Express) ---
import { Vortex } from '@teamvortexsoftware/vortex-node-22-sdk';
const vortex = new Vortex(process.env.VORTEX_API_KEY);
app.get('/api/invite-token', (req, res) => {
const token = vortex.generateToken({
user: { id: req.user.id, email: req.user.email }
});
res.json({ token });
});
// --- Frontend (React) ---
import { VortexInvite } from '@teamvortexsoftware/vortex-react';
function InvitePage() {
const { data } = useFetch('/api/invite-token');
return <VortexInvite token={data.token} />;
}
getInvitation()
Get a single invitation by ID
getInvitation(invitationId: string): Promise<InvitationResult>
Parameters:
Name Type Required Description invitationIdstring✓ The invitation ID to retrieve
Returns: Promise<InvitationResult> — The invitation details
const invitation = await vortex.getInvitation('inv-123');
console.log(invitation.status);
acceptInvitation()
Accept a single invitation
This is the recommended method for accepting invitations.
acceptInvitation(invitationId: string, user: AcceptUser): Promise<InvitationResult>
Parameters:
Name Type Required Description invitationIdstring✓ Single invitation ID to accept userAcceptUser✓ User object with email or phone (and optional name)
Returns: Promise<InvitationResult> — Invitation result
await vortex.acceptInvitation('inv-123', { email: 'user@example.com', name: 'John' });
generateJwt()Generate a JWT token for a user generateJwt(params: { [key: string]: any; user: User; }, options?: GenerateJwtOptions | undefined): string
Parameters: Name Type Required Description params{ [key: string]: any; user: User; }✓ Object containing user and optional additional properties options`GenerateJwtOptions undefined` Optional configuration (expiresIn)
Returns: string — JWT token string
const token = vortex.generateJwt({
user: {
id: "user-123",
email: "user@example.com",
adminScopes: ['autojoin']
}
});
// With custom expiration
const tokenWithCustomExpiry = vortex.generateJwt(
{ user: { id: "user-123", email: "user@example.com" } },
{ expiresIn: '24h' } // Custom expiration (default: 30 days)
);
getInvitationsByTarget()Get invitations by target (email, username, or phone number) getInvitationsByTarget(targetType: "email" | "username" | "phoneNumber", targetValue: string): Promise<InvitationResultBase[]>
Parameters: Name Type Required Description targetType`“email" "username" "phoneNumber”` ✓ The type of target identifier targetValuestring✓ The target value to search for
Returns: Promise<InvitationResultBase[]> — Array of invitation results matching the target
const invitations = await vortex.getInvitationsByTarget('email', 'user@example.com');
revokeInvitation()Revoke (delete) an invitation revokeInvitation(invitationId: string): Promise<{}>
Parameters: Name Type Required Description invitationIdstring✓ The invitation ID to revoke
Returns: Promise<{}> — Empty object on success
await vortex.revokeInvitation('inv-123');
acceptInvitations()Accept one or more invitations for a user acceptInvitations(invitationIds: string[], userOrTarget: AcceptUser | InvitationTarget | InvitationTarget[]): Promise<InvitationResult>
Parameters: Name Type Required Description invitationIdsstring[]✓ Array of invitation IDs to accept userOrTarget`AcceptUser InvitationTarget InvitationTarget[]` ✓ User object with email or phone, or legacy target format
Returns: Promise<InvitationResult> — The accepted invitation result
await vortex.acceptInvitations(['inv-123'], { email: 'user@example.com' });
deleteInvitationsByGroup()Delete all invitations for a specific group deleteInvitationsByGroup(groupType: string, groupId: string): Promise<{}>
Parameters: Name Type Required Description groupTypestring✓ The type of group (e.g., “team”, “organization”) groupIdstring✓ The group identifier
Returns: Promise<{}> — Empty objectgetInvitationsByGroup()Get all invitations for a specific group getInvitationsByGroup(groupType: string, groupId: string): Promise<InvitationResult[]>
Parameters: Name Type Required Description groupTypestring✓ The type of group (e.g., “team”, “organization”) groupIdstring✓ The group identifier
Returns: Promise<InvitationResult[]> — Array of invitation resultsdeleteInvitationsByScope()Delete all invitations for a specific scope deleteInvitationsByScope(scopeType: string, scope: string): Promise<{}>
Parameters: Name Type Required Description scopeTypestring✓ The type of scope (e.g., “team”, “organization”) scopestring✓ The scope identifier (customer’s scope ID)
Returns: Promise<{}> — Empty object
await vortex.deleteInvitationsByScope('team', 'team-123');
getInvitationsByScope()Get all invitations for a specific scope getInvitationsByScope(scopeType: string, scope: string): Promise<InvitationResult[]>
Parameters: Name Type Required Description scopeTypestring✓ The type of scope (e.g., “team”, “organization”) scopestring✓ The scope identifier (customer’s scope ID)
Returns: Promise<InvitationResult[]> — Array of invitation results
const invitations = await vortex.getInvitationsByScope('team', 'team-123');
reinvite()Resend an invitation (reinvite) reinvite(invitationId: string): Promise<InvitationResult>
Parameters: Name Type Required Description invitationIdstring✓ The invitation ID to resend
Returns: Promise<InvitationResult> — The updated invitation
const invitation = await vortex.reinvite('inv-123');
getAutojoinDomains()Get autojoin domains configured for a specific scope getAutojoinDomains(scopeType: string, scope: string): Promise<AutojoinDomainsResponse>
Parameters: Name Type Required Description scopeTypestring✓ The type of scope (e.g., “organization”, “team”, “project”) scopestring✓ The scope identifier (customer’s group ID)
Returns: Promise<AutojoinDomainsResponse> — Autojoin domains and associated invitation
const result = await vortex.getAutojoinDomains('organization', 'acme-org');
console.log(result.autojoinDomains); // [{ id: '...', domain: 'acme.com' }]
Configure autojoin domains for a specific scope This endpoint syncs autojoin domains - it will add new domains, remove domains
not in the provided list, and deactivate the autojoin invitation if all domains
are removed (empty array). configureAutojoin(params: ConfigureAutojoinRequest): Promise<AutojoinDomainsResponse>
Parameters: Name Type Required Description paramsConfigureAutojoinRequest✓ Configuration parameters
Returns: Promise<AutojoinDomainsResponse> — Updated autojoin domains and associated invitation
const result = await vortex.configureAutojoin({
scope: 'acme-org',
scopeType: 'organization',
scopeName: 'Acme Corporation',
domains: ['acme.com', 'acme.org'],
componentId: 'component-123',
});
syncInternalInvitation()Sync an internal invitation action (accept or decline) This method notifies Vortex that an internal invitation was accepted or declined
within your application, so Vortex can update the invitation status accordingly. syncInternalInvitation(params: SyncInternalInvitationRequest): Promise<SyncInternalInvitationResponse>
Parameters: Name Type Required Description paramsSyncInternalInvitationRequest✓ Sync parameters
Returns: Promise<SyncInternalInvitationResponse> — Object with processed count and invitation IDs
const result = await vortex.syncInternalInvitation({
creatorId: 'user-123',
targetValue: 'user-456',
action: 'accepted',
componentId: 'component-uuid-789',
});
console.log(`Processed ${result.processed} invitations`);
getEnvironments()List all environments configured for the authenticated account. Environments represent deployment targets (e.g., “development”, “staging”,
“production”) and form a promotion chain via nextEnvironmentId /
previousEnvironmentId. The account is derived from the API key. getEnvironments(): Promise<Environment[]>
Returns: Promise<Environment[]> — Array of environments belonging to the account
const environments = await vortex.getEnvironments();
const production = environments.find((env) => env.role === 'production');
getDeployments()List deployments for the authenticated account, optionally filtered by
widget, environment, or project. Each deployment row joins the deployment record with its target environment,
the widget being deployed, and the widget configurations referenced in the
deployment’s distribution. This is useful for resolving a
widgetConfigurationId from a componentId (widget) for a given
environment. The account is derived from the API key. getDeployments(params?: GetDeploymentsParams): Promise<DeploymentResult[]>
Parameters: Name Type Required Description paramsGetDeploymentsParamsFilter parameters
Returns: Promise<DeploymentResult[]> — Array of deployment results, each including widget, environment,
and associated widget configurations
// Resolve the active widgetConfigurationId for a widget in an environment
const deployments = await vortex.getDeployments({
widgetId: 'widget-uuid-456',
environmentId: 'env-uuid-789',
});
const widgetConfigurationId =
deployments[0]?.deployment.widgetConfigurationDistributions[0]
?.widgetConfigurationId;
Types
InvitationTargetTarget recipient of an invitation Field Type Required Description type`“email" "phone" "share" "internal”` ✓ Delivery channel type valuestring✓ Target address (email, phone number, or share link ID) name`string null undefined` Display name of the person being invited avatarUrl`string null undefined` Avatar URL for the person being invited
ScopeInput is used when creating JWTs - represents customer’s scope data
Supports both ‘id’ (legacy) and ‘groupId’ (preferred) for backward compatibility Field Type Required Description typestring✓ Scope type (e.g., ‘team’, ‘organization’, ‘workspace’) id`string undefined` ⚠️ Deprecated : Use scopeId instead scopeId`string undefined` The scope identifier (preferred) groupId`string undefined` ⚠️ Deprecated : Use scopeId instead namestring✓ Display name for the scope
Field Type Required Description typestring✓ Scope type (e.g., ‘team’, ‘organization’, ‘workspace’) id`string undefined` ⚠️ Deprecated : Use scopeId instead scopeId`string undefined` The scope identifier (preferred) groupId`string undefined` ⚠️ Deprecated : Use scopeId instead namestring✓ Display name for the scope
InvitationScopeInvitationScope represents a scope in API responses
This matches the MemberGroups table structure from the API Field Type Required Description idstring✓ Vortex internal UUID accountIdstring✓ Vortex account ID scopeIdstring✓ The customer’s scope ID (preferred) groupIdstring✓ ⚠️ Deprecated : Use scopeId instead typestring✓ Scope type (e.g., ‘workspace’, ‘team’) namestring✓ Display name for the scope createdAtstring✓ ISO timestamp when the scope was created
InvitationGroupField Type Required Description idstring✓ Vortex internal UUID accountIdstring✓ Vortex account ID scopeIdstring✓ The customer’s scope ID (preferred) groupIdstring✓ ⚠️ Deprecated : Use scopeId instead typestring✓ Scope type (e.g., ‘workspace’, ‘team’) namestring✓ Display name for the scope createdAtstring✓ ISO timestamp when the scope was created
InvitationAcceptanceRecord of a user accepting an invitation Field Type Required Description idstring✓ Unique acceptance record ID accountIdstring✓ Vortex account ID acceptedAtstring✓ ISO timestamp when the invitation was accepted targetInvitationTarget✓ The user who accepted the invitation
InvitationResultBaseBase invitation result without target information.
Used by endpoints like getInvitationsByTarget where target is already known. Field Type Required Description idstring✓ Unique invitation identifier accountIdstring✓ Vortex account ID that owns this invitation clickThroughsnumber✓ Number of times the invitation link was clicked formSubmissionData`Record<string, any> null` ✓ Invitation form data submitted by the user, including email addresses of invitees and the values of any custom fields. configurationAttributes`Record<string, any> null` ✓ ⚠️ Deprecated : Use formSubmissionData instead. This field contains the same data. attributes`Record<string, any> null` ✓ Custom attributes attached to this invitation createdAtstring✓ ISO timestamp when the invitation was created deactivatedboolean✓ Whether the invitation has been deactivated deliveryCountnumber✓ Number of delivery attempts made deliveryTypes`(“email" "phone" "share" "internal”)[]` ✓ Delivery channels used for this invitation foreignCreatorIdstring✓ Your user ID who created this invitation invitationType`“single_use" "multi_use" "autojoin”` ✓ Type of invitation: single_use (one accept), multi_use (unlimited), or autojoin (domain-based) modifiedAt`string null` ✓ ISO timestamp when the invitation was last modified status`“queued" "sending" "sent" "delivered" "accepted" "shared" "unfurled" "accepted_elsewhere”` ✓ Current status of the invitation viewsnumber✓ Number of times the invitation was viewed widgetConfigurationIdstring✓ ID of the component configuration used scopesInvitationScope[]✓ Scopes associated with this invitation (preferred) groupsInvitationScope[]✓ ⚠️ Deprecated : Use scopes instead accepts`InvitationAcceptance[] undefined` List of users who accepted this invitation expiredboolean✓ Whether the invitation has expired expires`string undefined` ISO timestamp when the invitation expires source`string undefined` Source identifier (e.g., campaign name) subtype`string null undefined` Customer-defined subtype for categorizing this invitation (e.g., pymk, find-friends, profile-button) creatorName`string null undefined` Display name of the invitation creator creatorAvatarUrl`string null undefined` Avatar URL of the invitation creator
InvitationResultFull invitation result including target information.
Used by getInvitation, getInvitationsByScope, and other endpoints that return targets. Field Type Required Description idstring✓ Unique invitation identifier accountIdstring✓ Vortex account ID that owns this invitation clickThroughsnumber✓ Number of times the invitation link was clicked formSubmissionData`Record<string, any> null` ✓ Invitation form data submitted by the user, including email addresses of invitees and the values of any custom fields. configurationAttributes`Record<string, any> null` ✓ ⚠️ Deprecated : Use formSubmissionData instead. This field contains the same data. attributes`Record<string, any> null` ✓ Custom attributes attached to this invitation createdAtstring✓ ISO timestamp when the invitation was created deactivatedboolean✓ Whether the invitation has been deactivated deliveryCountnumber✓ Number of delivery attempts made deliveryTypes`(“email" "phone" "share" "internal”)[]` ✓ Delivery channels used for this invitation foreignCreatorIdstring✓ Your user ID who created this invitation invitationType`“single_use" "multi_use" "autojoin”` ✓ Type of invitation: single_use (one accept), multi_use (unlimited), or autojoin (domain-based) modifiedAt`string null` ✓ ISO timestamp when the invitation was last modified status`“queued" "sending" "sent" "delivered" "accepted" "shared" "unfurled" "accepted_elsewhere”` ✓ Current status of the invitation viewsnumber✓ Number of times the invitation was viewed widgetConfigurationIdstring✓ ID of the component configuration used scopesInvitationScope[]✓ Scopes associated with this invitation (preferred) groupsInvitationScope[]✓ ⚠️ Deprecated : Use scopes instead accepts`InvitationAcceptance[] undefined` List of users who accepted this invitation expiredboolean✓ Whether the invitation has expired expires`string undefined` ISO timestamp when the invitation expires source`string undefined` Source identifier (e.g., campaign name) subtype`string null undefined` Customer-defined subtype for categorizing this invitation (e.g., pymk, find-friends, profile-button) creatorName`string null undefined` Display name of the invitation creator creatorAvatarUrl`string null undefined` Avatar URL of the invitation creator targetInvitationTarget[]✓ List of invitation targets (recipients)
AcceptUserUser type for accepting invitations
Requires either email or phone (or both) Field Type Required Description email`string undefined` Email address of the accepting user phone`string undefined` Phone number of the accepting user name`string undefined` Display name of the accepting user isExisting`boolean undefined` Whether the accepting user is an existing user in your system. Set to true if the user was already registered before accepting the invitation. Set to false if this is a new user signup. Leave undefined if unknown. Used for analytics to track new vs existing user conversions.
AcceptInvitationRequestRequest body for accepting invitations Field Type Required Description invitationIdsstring[]✓ Array of invitation IDs to accept userAcceptUser✓ Information about the user accepting the invitations
AcceptInvitationRequestLegacyLegacy request body for accepting invitations Field Type Required Description invitationIdsstring[]✓ Array of invitation IDs to accept targetInvitationTarget✓ Target information (legacy format)
SyncInternalInvitationRequestRequest body for syncing an internal invitation action Field Type Required Description creatorIdstring✓ The inviter’s user ID targetValuestring✓ The invitee’s user ID action`“accepted" "declined”` ✓ The action taken: “accepted” or “declined” componentIdstring✓ The widget component UUID
SyncInternalInvitationResponseResponse from syncing an internal invitation action Field Type Required Description processednumber✓ Number of invitations processed invitationIdsstring[]✓ IDs of the invitations that were processed
UserUser type for JWT generation
Only id is required. Email is optional but recommended for invitation attribution. Field Type Required Description idstring✓ Unique user identifier in your system email`string undefined` User’s email address (optional, used for reply-to in invitation emails) name`string undefined` User’s display name (preferred) avatarUrl`string undefined` User’s avatar URL (preferred) userName`string undefined` ⚠️ Deprecated : Use name instead userAvatarUrl`string undefined` ⚠️ Deprecated : Use avatarUrl instead adminScopes`string[] undefined` Admin scope permissions (e.g., [‘autojoin’]) allowedEmailDomains`string[] undefined` Optional list of allowed email domains for invitation restrictions. When present, email invitations will only be allowed to addresses matching one of these domains (e.g., [‘acme.com’, ‘acme.org’]). Domain matching is case-insensitive.
AutojoinDomainAutojoin domain configuration
Allows users with matching email domains to automatically join a scope Field Type Required Description idstring✓ Unique domain configuration ID domainstring✓ Email domain (e.g., ‘acme.com’)
AutojoinDomainsResponseResponse from autojoin API endpoints Field Type Required Description autojoinDomainsAutojoinDomain[]✓ List of configured autojoin domains invitation`InvitationResult null` ✓ The autojoin invitation if one exists, null otherwise
Request body for configuring autojoin domains Field Type Required Description scopestring✓ Scope ID in your system scopeTypestring✓ Type of scope (e.g., ‘team’, ‘organization’) scopeName`string undefined` Display name for the scope domainsstring[]✓ List of email domains that can autojoin (e.g., [‘acme.com’, ‘acme.org’]) componentIdstring✓ Component ID to use for autojoin invitations metadata`Record<string, any> undefined` Custom metadata to attach to autojoin invitations
InviterInformation about the user creating the invitation (the inviter) Field Type Required Description userIdstring✓ The internal user ID of the person creating the invitation (from your system) userEmail`string undefined` The email address of the person creating the invitation name`string undefined` The display name of the person creating the invitation (preferred) avatarUrl`string undefined` Avatar URL for the person creating the invitation (preferred) userName`string undefined` ⚠️ Deprecated : Use name instead userAvatarUrl`string undefined` ⚠️ Deprecated : Use avatarUrl instead
GenerateTokenUserUser object for generateToken - flexible structure
Only id is required for secure attribution Field Type Required Description id`string number` ✓ User ID - required for secure attribution email`string undefined` User’s email address name`string undefined` User’s display name phone`string undefined` User’s phone number avatarUrl`string undefined` User’s avatar URL
GenerateTokenDataPayload structure for generateToken method
All fields are optional - sign only what you need Field Type Required Description component`string undefined` Widget component ID trigger`string undefined` DOM selector for trigger button embed`string undefined` DOM selector for embed container user`GenerateTokenUser undefined` User information - include id for secure attribution scope`string undefined` Scope/workspace identifier vars`Record<string, any> undefined` Template variables for customization
GenerateJwtOptionsOptions for generateJwt method Field Type Required Description expiresIn`string number undefined` JWT expiration time
String format: ‘5m’, ‘1h’, ‘24h’, ‘7d’ (minutes, hours, days)
Number format: seconds
Default: 30 days (2592000 seconds) |
GenerateTokenOptionsOptions for generateToken method Field Type Required Description expiresIn`string number undefined` Token expiration time
String format: ‘5m’, ‘1h’, ‘24h’, ‘7d’ (minutes, hours, days)
Number format: seconds
Default: ‘30d’ (30 days) |
EnvironmentEnvironment as returned by the Vortex API /environments endpoint.
Environments represent deployment targets (e.g., “development”, “staging”, “production”). Note: this type matches FullEnvironmentResultDto from the public API and includes
sortingWeight. The shape embedded in deployment results (see DeploymentEnvironment)
is a different, smaller DTO that does NOT include sortingWeight. Field Type Required Description idstring✓ Vortex internal UUID for this environment name`string null` ✓ Display name of the environment (e.g., “production”) description`string null undefined` Optional description of the environment nextEnvironmentId`string null undefined` ID of the next environment in the promotion chain, if any previousEnvironmentId`string null undefined` ID of the previous environment in the promotion chain, if any role`string null undefined` Role of the environment (e.g., “production”, “staging”) nextEnvironmentName`string null undefined` Display name of the next environment in the promotion chain previousEnvironmentName`string null undefined` Display name of the previous environment in the promotion chain sortingWeightnumber✓ Sorting weight used to order environments in the UI
DeploymentEnvironmentEnvironment shape embedded in deployment results. This matches EnvironmentResultDto from
apps/public-api/src/deployments/dto/deployment-result.dto.ts, which is a
narrower DTO than the one returned by the /environments endpoint. In
particular, it does NOT include sortingWeight and name is non-nullable. Use Environment for results from getEnvironments() and
DeploymentEnvironment for the environment field of DeploymentResult. Field Type Required Description idstring✓ Vortex internal UUID for this environment namestring✓ Display name of the environment (e.g., “production”) description`string null` ✓ Optional description of the environment nextEnvironmentId`string null` ✓ ID of the next environment in the promotion chain, if any previousEnvironmentId`string null` ✓ ID of the previous environment in the promotion chain, if any role`string null` ✓ Role of the environment (e.g., “production”, “staging”) nextEnvironmentName`string null` ✓ Display name of the next environment in the promotion chain previousEnvironmentName`string null` ✓ Display name of the previous environment in the promotion chain
DeploymentDeployment metadata as returned by the Vortex API.
Represents a single deployment record describing how widget configurations
are distributed within an environment. Field Type Required Description idstring✓ Vortex internal UUID for this deployment namestring✓ Display name of the deployment description`string null undefined` Optional description of the deployment widgetConfigurationDistributionsWidgetConfigurationDistribution[]✓ Distribution of widget configurations served by this deployment createdAtstring✓ ISO timestamp when the deployment was created deactivatedboolean✓ Whether this deployment has been deactivated
Distribution entry used to split traffic across widget configurations. Field Type Required Description widgetConfigurationIdstring✓ Vortex internal UUID for the widget configuration distributionPercentagenumber✓ Percentage of users that will receive this configuration (0-100)
Widget summary as included in deployment results. Field Type Required Description idstring✓ Vortex internal UUID for the widget namestring✓ Widget display name typestring✓ Widget type (e.g., “vortex-invite”) projectIdstring✓ ID of the project the widget belongs to
Widget configuration summary as included in deployment results. Field Type Required Description idstring✓ Vortex internal UUID for the widget configuration versionstring✓ Version label of the widget configuration statusstring✓ Status of the widget configuration
DeploymentResultSingle deployment row returned by getDeployments().
Joins deployment, environment, widget and widget configuration metadata. Field Type Required Description accountIdstring✓ Vortex account ID that owns this deployment deploymentDeployment✓ Deployment metadata environmentDeploymentEnvironment✓ Environment the deployment targets.
Note: this is the narrower DeploymentEnvironment shape embedded in
deployment responses, not the full Environment type returned by
getEnvironments(). It does not include sortingWeight. |
| widget | DeploymentWidget | ✓ | Widget being deployed |
| widgetConfigurations | DeploymentWidgetConfiguration[] | ✓ | Widget configurations referenced by the deployment | GetDeploymentsParamsFilter parameters for getDeployments(). All fields are optional.
The account is derived from the API key. Field Type Required Description widgetId`string undefined` Optional widget ID filter environmentId`string undefined` Optional environment ID filter projectId`string undefined` Optional project ID filter
Webhooks
Webhooks let your server receive real-time notifications when events happen in Vortex. Use them to sync invitation state with your database, trigger onboarding flows, update your CRM, or send internal notifications.
Setup
Go to your Vortex dashboard → Integrations → Webhooks tab
Click “Add Webhook”
Enter your endpoint URL (must be HTTPS in production)
Copy the signing secret — you’ll use this to verify webhook signatures
Select which events you want to receive
Example
Express.js webhook handler
import express from 'express';
import { VortexWebhooks, isWebhookEvent } from '@teamvortexsoftware/vortex-node-22-sdk';
const app = express();
const webhooks = new VortexWebhooks({
secret: process.env.VORTEX_WEBHOOK_SECRET!,
});
// Important: Use raw body for signature verification
app.post('/webhooks/vortex', express.raw({ type: 'application/json' }), (req, res) => {
try {
const event = webhooks.constructEvent(
req.body,
req.headers['x-vortex-signature'] as string
);
if (isWebhookEvent(event)) {
switch (event.type) {
case 'invitation.accepted':
// User accepted an invitation — activate their account
console.log('Invitation accepted:', event.data.targetEmail);
break;
case 'member.created':
// New member joined via invitation
console.log('New member:', event.data);
break;
}
}
res.json({ received: true });
} catch (err) {
console.error('Webhook error:', err);
res.status(400).send('Webhook Error');
}
});
Events
Event Description invitation.createdA new invitation was created invitation.acceptedAn invitation was accepted by the recipient invitation.deactivatedAn invitation was deactivated (revoked or expired) invitation.email.deliveredInvitation email was successfully delivered invitation.email.bouncedInvitation email bounced (invalid address) invitation.email.openedRecipient opened the invitation email invitation.link.clickedRecipient clicked the invitation link invitation.reminder.sentA reminder email was sent for a pending invitation member.createdA new member was created from an accepted invitation group.member.addedA member was added to a scope/group deployment.createdA new deployment configuration was created deployment.deactivatedA deployment was deactivated abtest.startedAn A/B test was started abtest.winner_declaredAn A/B test winner was declared email.complainedRecipient marked the email as spam
Use Cases
Activate users on acceptance — When invitation.accepted fires, mark the user as active in your database and trigger your onboarding flow.
Track invitation performance — Monitor email.delivered, email.opened, and link.clicked events to measure invitation funnel metrics.
Sync team membership — Use member.created and group.member.added to keep your internal membership records in sync.
Alert on delivery issues — Watch for email.bounced events to proactively reach out via alternative channels.
Error Handling
Error Description VortexWebhookSignatureErrorThrown when webhook signature verification fails. Check that you are using the raw request body (not parsed JSON) and the correct signing secret from your Vortex dashboard. ErrorThrown for validation errors (e.g., missing API key, invalid user ID in generateToken/generateJwt)
Resources