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.
Installation
dotnet add package TeamVortexSoftware.VortexSDK
Quick Start
Generate a secure token for Vortex components
using TeamVortexSoftware . VortexSDK ;
var client = new VortexClient ( Environment . GetEnvironmentVariable ( "VORTEX_API_KEY" ));
var payload = new GenerateTokenPayload
{
User = new TokenUser { Id = "user-123" , Email = "user@example.com" }
};
var token = client . GenerateToken ( payload );
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 .NET project dotnet add package TeamVortexSoftware . VortexSDK
Initialize the client
Create a Vortex client with your API key (keep this on the server!) using TeamVortexSoftware . VortexSDK ;
var client = new VortexClient (
Environment . GetEnvironmentVariable ( "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 var token = client . GenerateToken ( new GenerateTokenPayload
{
User = new TokenUser { Id = currentUser . Id }
});
Pass the token to your frontend
Include the token in your page response or API response return Ok ( new { vortexToken = token });
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()
Generate a signed token for use with Vortex widgets
GenerateToken(GenerateTokenPayload payload, GenerateTokenOptions? options): string
Parameters:
Name Type Required Description payloadGenerateTokenPayload✓ Data to sign (user, component, scope, vars, etc.) optionsGenerateTokenOptions?Optional configuration (ExpiresIn)
Returns: string — Signed JWT token string
GetInvitationAsync()
Get a specific invitation by ID
GetInvitationAsync(string invitationId): Task<Invitation>
Parameters:
Name Type Required Description invitationIdstring✓ The invitation ID
Returns: Task<Invitation> — The invitation details
AcceptInvitationAsync()
Accept a single invitation (recommended method)
AcceptInvitationAsync(string invitationId, AcceptUser user): Task<Invitation>
Parameters:
Name Type Required Description invitationIdstring✓ Single invitation ID to accept userAcceptUser✓ User with email or phone (and optional name)
Returns: Task<Invitation> — Invitation result
GetInvitationsByTargetAsync()Get invitations by target (email or sms) GetInvitationsByTargetAsync(string targetType, string targetValue): Task<List<Invitation>>
Parameters: Name Type Required Description targetTypestring✓ Type of target (email, phone) targetValuestring✓ The target value
Returns: Task<List<Invitation>> — List of invitationsRevokeInvitationAsync()Revoke (delete) an invitation RevokeInvitationAsync(string invitationId): Task
Parameters: Name Type Required Description invitationIdstring✓ The invitation ID to revoke
Returns: TaskAcceptInvitationsAsync()Accept multiple invitations using the new User format (preferred) AcceptInvitationsAsync(List<string> invitationIds, AcceptUser user): Task<Invitation>
Parameters: Name Type Required Description invitationIdsList<string>✓ List of invitation IDs to accept userAcceptUser✓ User with email or phone (and optional name)
Returns: Task<Invitation> — Invitation resultDeleteInvitationsByScopeAsync()Delete all invitations for a specific scope DeleteInvitationsByScopeAsync(string groupType, string groupId): Task
Parameters: Name Type Required Description groupTypestring✓ The scope type (organization, team, etc.) groupIdstring✓ The scope identifier
Returns: TaskGetInvitationsByScopeAsync()Get all invitations for a specific scope GetInvitationsByScopeAsync(string groupType, string groupId): Task<List<Invitation>>
Parameters: Name Type Required Description groupTypestring✓ The scope type (organization, team, etc.) groupIdstring✓ The scope identifier
Returns: Task<List<Invitation>> — List of invitations for the scopeReinviteAsync()Reinvite a user (send invitation again) ReinviteAsync(string invitationId): Task<Invitation>
Parameters: Name Type Required Description invitationIdstring✓ The invitation ID to reinvite
Returns: Task<Invitation> — The reinvited invitation resultCreateInvitationAsync()Create an invitation from your backend. This method allows you to create invitations programmatically using your API key, without requiring a user JWT token. Useful for server-side invitation creation, such as “People You May Know” flows or admin-initiated invitations. CreateInvitationAsync(CreateInvitationRequest request): Task<CreateInvitationResponse>
Parameters: Name Type Required Description requestCreateInvitationRequest✓ The create invitation request
Returns: Task<CreateInvitationResponse> — CreateInvitationResponse with id, shortLink, status, and createdAt
// Create an email invitation
var request = new CreateInvitationRequest(
"widget-config-123",
CreateInvitationTarget.Email("invitee@example.com"),
new Inviter("user-456", "inviter@example.com", "John Doe")
);
request.Groups = new List<CreateInvitationScope>
{
new("team", "team-789", "Engineering")
};
var response = await client.CreateInvitationAsync(request);
// Create an internal invitation (PYMK flow)
var pymkRequest = new CreateInvitationRequest(
"widget-config-123",
CreateInvitationTarget.Internal("internal-user-abc"),
new Inviter("user-456")
);
pymkRequest.Source = "pymk";
var response = await client.CreateInvitationAsync(pymkRequest);
GetAutojoinDomainsAsync()Get autojoin domains configured for a specific scope GetAutojoinDomainsAsync(string scopeType, string scope): Task<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: Task<AutojoinDomainsResponse> — AutojoinDomainsResponse with autojoin domains and invitationConfigure autojoin domains for a specific scope ConfigureAutojoinAsync(ConfigureAutojoinRequest request): Task<AutojoinDomainsResponse>
Parameters: Name Type Required Description requestConfigureAutojoinRequest✓ The configure autojoin request
Returns: Task<AutojoinDomainsResponse> — AutojoinDomainsResponse with updated autojoin domainsSyncInternalInvitationAsync()Sync an internal invitation action (accept or decline) SyncInternalInvitationAsync(SyncInternalInvitationRequest request): Task<SyncInternalInvitationResponse>
Parameters: Name Type Required Description requestSyncInternalInvitationRequest✓ The sync internal invitation request
Returns: Task<SyncInternalInvitationResponse> — SyncInternalInvitationResponse with processed count and invitationIds
var request = new SyncInternalInvitationRequest("user-123", "user-456", "accepted", "component-uuid");
var response = await client.SyncInternalInvitationAsync(request);
Console.WriteLine($"Processed: {response.Processed}");
Types
GenerateTokenPayloadPayload for GenerateToken - used to generate secure tokens for Vortex components Field Type Required Description userTokenUser?The authenticated user who will be using the Vortex component componentstring?Component ID to generate token for (from your Vortex dashboard) scopestring?Scope identifier to restrict invitations to a specific team/org (format: “scopeType:scopeId”) varsDictionary<string, object>?Custom variables to pass to the component for template rendering
TokenUserUser data for GenerateToken - represents the authenticated user sending invitations Field Type Required Description idstring?Unique identifier for the user in your system. Used to attribute invitations and track referral chains. namestring?Display name shown to invitation recipients (e.g., “John invited you”) emailstring?User’s email address. Used for reply-to in invitation emails. avatarUrlstring?URL to user’s avatar image. Displayed in invitation emails and widgets. adminScopesList<string>?List of scope IDs where this user has admin privileges (e.g., [“team:team-123”])
AcceptUserUser data for accepting invitations - identifies who accepted the invitation Field Type Required Description emailstring?Email address of the user accepting. At least one of Email or Phone is required. phonestring?Phone number with country code (e.g., “+15551234567”). At least one of Email or Phone is required. namestring?Display name of the accepting user (shown in notifications to inviter) isExistingbool?Whether user was already registered. true=existing, false=new signup, null=unknown. Used for conversion analytics.
InvitationComplete invitation details as returned by the Vortex API Field Type Required Description idstring✓ Unique identifier for this invitation accountIdstringYour Vortex account ID clickThroughsintNumber of times the invitation link was clicked formSubmissionDataDictionary<string, object>?Invitation form data submitted by the user, including email addresses of invitees and the values of any custom fields. configurationAttributesDictionary<string, object>?attributesDictionary<string, object>?Custom attributes attached to this invitation createdAtstringISO 8601 timestamp when the invitation was created deactivatedboolWhether this invitation has been revoked or expired deliveryCountintNumber of times the invitation was sent (including reminders) deliveryTypesList<DeliveryType>Channels used to deliver this invitation (email, sms, share link) foreignCreatorIdstringYour internal user ID for the person who created this invitation invitationTypeInvitationTypeType of invitation: single_use (1:1), multi_use (1:many), or autojoin modifiedAtstring?ISO 8601 timestamp of last modification statusInvitationStatusCurrent status: queued, sending, sent, delivered, accepted, shared, unfurled targetList<InvitationTarget>List of invitation recipients with their contact info and status viewsintNumber of times the invitation page was viewed widgetConfigurationIdstringWidget configuration ID used for this invitation deploymentIdstringDeployment ID this invitation belongs to groupsList<InvitationScope>Scopes (teams/orgs) this invitation grants access to acceptsList<InvitationAcceptance>?List of acceptance records if the invitation was accepted (optional) scopestring?Primary scope identifier (e.g., “team-123”) scopeTypestring?Type of the primary scope (e.g., “team”, “organization”) expiredboolWhether this invitation has passed its expiration date expiresstring?ISO 8601 timestamp when this invitation expires metadataDictionary<string, object>?Custom metadata attached to this invitation passThroughstring?Pass-through data returned unchanged in webhooks and callbacks sourcestring?Source identifier for tracking (e.g., “ios-app”, “web-dashboard”) subtypestring?Subtype for analytics segmentation (e.g., “pymk”, “find-friends”) creatorNamestring?Display name of the user who created this invitation creatorAvatarUrlstring?Avatar URL of the user who created this invitation
InvitationTargetRepresents the target recipient of an invitation Field Type Required Description typeInvitationTargetType✓ Delivery channel: email, phone, share (link), or internal (in-app) valuestringTarget address: email, phone number with country code, or share link ID namestring?Display name of the recipient (e.g., “John Doe”) avatarUrlstring?Avatar URL for the recipient, shown in invitation lists and widgets
InvitationScopeInvitation group from API responses This matches the MemberGroups table structure from the API Field Type Required Description idstring✓ Vortex internal UUID accountIdstringVortex account ID groupIdstringCustomer’s group ID (the ID they provided to Vortex) typestring✓ Group type (e.g., “workspace”, “team”) namestringGroup name createdAtstringISO 8601 timestamp when the group was created
CreateInvitationTargetTarget recipient when creating an invitation Field Type Required Description typeCreateInvitationTargetTypeEnum✓ Delivery channel: email, phone, or internal (in-app) valuestringTarget address: email, phone number (with country code), or internal user ID namestring?Display name of the recipient (shown in invitation emails and UI) avatarUrlstring?Avatar URL for the recipient (displayed in invitation lists)
InviterInformation about the user sending the invitation - used for attribution and display Field Type Required Description userIdstring✓ Your internal user ID for the inviter (required for attribution) userEmailstring?Inviter’s email address (used for reply-to and identification) namestring?Display name shown to recipients (e.g., “John invited you to…”) avatarUrlstring?Avatar URL displayed in invitation emails and widgets
UserUser data for JWT generation - represents the authenticated user sending invitations. Only Id is required. Email is optional but recommended for invitation attribution. Field Type Required Description idstring✓ Your internal user ID (required for invitation attribution) emailstring?User’s email address (optional, used for reply-to in invitation emails) namestring?Display name shown to recipients (e.g., “John invited you”) avatarUrlstring?Avatar URL displayed in invitation emails and widgets (must be HTTPS) adminScopesList<string>?List of scopes where user has admin privileges (e.g., [“autojoin”]) allowedEmailDomainsList<string>?Restrict invitations to these email domains (e.g., [“acme.com”])
IdentifierIdentifier for a user - used in JWT generation to link user across channels Field Type Required Description typestring✓ Identifier type: “email”, “phone”, “username”, or custom type valuestringThe identifier value (email address, phone number, etc.)
GroupScope/group for JWT generation - defines user’s team/org membership in tokens Field Type Required Description typestring✓ Scope type (e.g., “team”, “organization”, “workspace”) idstring?Legacy scope identifier. Use Scope/groupId instead. groupIdstring?Your internal scope/group identifier (preferred) namestringDisplay name for the scope (e.g., “Engineering Team”)
InvitationAcceptanceRecord of an invitation being accepted Field Type Required Description idstring✓ Unique identifier for this acceptance record accountIdstringYour Vortex account ID acceptedAtstringISO 8601 timestamp when the invitation was accepted targetInvitationTarget?The target that accepted the invitation
CreateInvitationScopeGroup information for creating invitations Field Type Required Description typestring✓ Group type (e.g., “team”, “organization”) groupIdstringYour internal group ID namestringDisplay name of the group
UnfurlConfigConfiguration for link unfurl (Open Graph) metadata. Controls how the invitation link appears when shared on social platforms or messaging apps. Field Type Required Description titlestring?The title shown in link previews (og:title) descriptionstring?The description shown in link previews (og:description) imagestring?The image URL shown in link previews (og:image) - must be HTTPS typestring?The Open Graph type (og:type) - e.g., ‘website’, ‘article’, ‘product’ siteNamestring?The site name shown in link previews (og:site_name)
AutojoinDomainAutojoin domain - users with matching email domains automatically join the scope Field Type Required Description idstring✓ Unique identifier for this autojoin configuration domainstringEmail domain that triggers autojoin (e.g., “acme.com”)
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
ASP.NET Core webhook handler
using TeamVortexSoftware.VortexSDK;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("webhooks")]
public class WebhookController : ControllerBase
{
private readonly VortexWebhooks _webhooks = new(
Environment.GetEnvironmentVariable("VORTEX_WEBHOOK_SECRET")
);
[HttpPost("vortex")]
public IActionResult HandleWebhook(
[FromBody] string body,
[FromHeader(Name = "X-Vortex-Signature")] string signature)
{
// Verify the signature
if (!_webhooks.VerifySignature(body, signature))
return BadRequest("Invalid signature");
// Parse the event
var webhookEvent = _webhooks.ParseEvent(body);
switch (webhookEvent.Type)
{
case "invitation.accepted":
// User accepted an invitation — activate their account
Console.WriteLine($"Accepted: {webhookEvent.Data}");
break;
case "member.created":
// New member joined via invitation
Console.WriteLine($"New member: {webhookEvent.Data}");
break;
}
return Ok(new { received = true });
}
}
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 VortexExceptionThrown for validation errors (e.g., missing API key, invalid parameters) or API failures
Resources