Skip to main content
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

<dependency>
  <groupId>com.vortexsoftware</groupId>
  <artifactId>vortex-java-sdk</artifactId>
</dependency>

Quick Start

Generate a secure token for Vortex components
VortexClient client = new VortexClient(System.getenv("VORTEX_API_KEY"));

GenerateTokenPayload payload = new GenerateTokenPayload()
    .setUser(new TokenUser().setId("user-123").setEmail("user@example.com"));

String 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.
1

Install the backend SDK

Add this SDK to your Java project
<dependency>
<groupId>com.vortexsoftware</groupId>
<artifactId>vortex-java-sdk</artifactId>
</dependency>
2

Initialize the client

Create a Vortex client with your API key (keep this on the server!)
import com.vortexsoftware.sdk.VortexClient;

VortexClient client = new VortexClient(System.getenv("VORTEX_API_KEY"));
3

Generate a token for the current user

When a user loads a page with a Vortex component, generate a signed token on your server
String token = client.generateToken(
new GenerateTokenPayload().setUser(
    new TokenUser().setId(currentUser.getId())
)
);
4

Pass the token to your frontend

Include the token in your page response or API response
response.put("vortexToken", token);
5

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} />
6

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): String
Parameters:
NameTypeRequiredDescription
payloadGenerateTokenPayloadData to sign (user, component, scope, vars, etc.)
Returns: String — Signed JWT token string

getInvitation()

Get a specific invitation by ID
getInvitation(String invitationId): InvitationResult
Parameters:
NameTypeRequiredDescription
invitationIdStringThe invitation ID
Returns: InvitationResult — The invitation details
InvitationResult invitation = client.getInvitation("inv-123");
System.out.println("Status: " + invitation.getStatus());

acceptInvitation()

Accept a single invitation (recommended method)
acceptInvitation(String invitationId, AcceptUser user): InvitationResult
Parameters:
NameTypeRequiredDescription
invitationIdStringSingle invitation ID to accept
userAcceptUserUser object with email and/or phone
Returns: InvitationResult — The accepted invitation result
AcceptUser user = new AcceptUser()
.setEmail("user@example.com")
.setName("John Doe");
InvitationResult result = client.acceptInvitation("inv-123", user);

generateJwt()

Generate a JWT using the same algorithm as the Node.js SDK
generateJwt(Object> params): String
Parameters:
NameTypeRequiredDescription
paramsObject&gt;Map containing “user” key with User object
Returns: String — JWT token string

getInvitationsByTarget()

Get invitations by target (email, username, phoneNumber)
getInvitationsByTarget(String targetType, String targetValue): List<InvitationResult>
Parameters:
NameTypeRequiredDescription
targetTypeStringType of target (email, phone, etc.)
targetValueStringThe target value
Returns: List&lt;InvitationResult&gt; — List of invitations

revokeInvitation()

Revoke (delete) an invitation
revokeInvitation(String invitationId): void
Parameters:
NameTypeRequiredDescription
invitationIdStringThe invitation ID to revoke
Returns: void

deleteInvitationsByScope()

Delete all invitations for a specific scope
deleteInvitationsByScope(String scopeType, String scope): void
Parameters:
NameTypeRequiredDescription
scopeTypeStringThe scope type (organization, team, etc.)
scopeStringThe scope identifier
Returns: void

getInvitationsByScope()

Get all invitations for a specific scope
getInvitationsByScope(String scopeType, String scope): List<InvitationResult>
Parameters:
NameTypeRequiredDescription
scopeTypeStringThe scope type (organization, team, etc.)
scopeStringThe scope identifier
Returns: List&lt;InvitationResult&gt; — List of invitations for the scope

reinvite()

Reinvite a user (send invitation again)
reinvite(String invitationId): InvitationResult
Parameters:
NameTypeRequiredDescription
invitationIdStringThe invitation ID to reinvite
Returns: InvitationResult — The reinvited invitation result

getAutojoinDomains()

Get autojoin domains configured for a specific scope
getAutojoinDomains(String scopeType, String scope): AutojoinDomainsResponse
Parameters:
NameTypeRequiredDescription
scopeTypeStringThe type of scope (e.g., “organization”, “team”, “project”)
scopeStringThe scope identifier (customer’s group ID)
Returns: AutojoinDomainsResponse — AutojoinDomainsResponse with autojoin domains and invitation

configureAutojoin()

Configure autojoin domains for a specific scope
configureAutojoin(ConfigureAutojoinRequest request): AutojoinDomainsResponse
Parameters:
NameTypeRequiredDescription
requestConfigureAutojoinRequestThe configure autojoin request
Returns: AutojoinDomainsResponse — AutojoinDomainsResponse with updated autojoin domains

Types

GenerateTokenPayload

FieldTypeRequiredDescription
userTokenUserThe authenticated user who will be using the Vortex component. Required for most operations to attribute invitations correctly.
componentStringComponent ID to generate token for (from your Vortex dashboard). If not specified, uses the default component for your account.
triggerStringTrigger context for the invitation (e.g., “signup”, “share-button”, “referral-page”). Used for analytics to track which UI elements drive the most invitations.
embedStringEmbed mode identifier for embedded invitation widgets. Determines how the component renders in your UI.
scopeStringScope identifier to restrict invitations to a specific team/org/workspace. Format: “scopeType:scopeId” (e.g., “team:team-123”).

TokenUser

FieldTypeRequiredDescription
idStringUnique identifier for the user in your system. Used to attribute invitations and track referral chains.
nameStringDisplay name shown to invitation recipients (e.g., “John invited you”). If not provided, falls back to email or a generic message.
emailStringUser’s email address. Used for reply-to in invitation emails and shown to recipients so they know who invited them.
avatarUrlStringURL to user’s avatar image. Displayed in invitation emails and widgets to personalize the invitation experience.
adminScopesList&lt;String&gt;List of scope IDs where this user has admin privileges. Admins can manage invitations and view analytics for these scopes. Format: [“scopeType:scopeId”, …] (e.g., [“team:team-123”, “org:org-456”]).
allowedEmailDomainsList&lt;String&gt;Restrict invitations to specific email domains. If set, users can only invite people with emails matching these domains. Useful for enterprise accounts (e.g., [“acme.com”, “acme.co.uk”]).

AcceptUser

FieldTypeRequiredDescription
emailStringEmail address of the user accepting the invitation. At least one of email or phone is required.
phoneStringPhone number of the user accepting the invitation. At least one of email or phone is required. Include country code (e.g., “+1555123456”).
nameStringDisplay name of the accepting user. Used in notifications to the inviter (e.g., “John Doe accepted your invitation”).
isExistingBooleanWhether the accepting user was already registered in your system. Set to true for existing users, false for new signups, null if unknown. Used for analytics to track new vs existing user conversion rates.

InvitationResult

FieldTypeRequiredDescription
idStringUnique identifier for this invitation
accountIdStringYour Vortex account ID
clickThroughsintNumber of times the invitation link was clicked
createdAtStringISO 8601 timestamp when the invitation was created
deactivatedbooleanWhether this invitation has been revoked or expired
deliveryCountintNumber of times the invitation was sent (including reminders)
deliveryTypesList&lt;DeliveryType&gt;Channels used to deliver this invitation (email, sms, share link)
foreignCreatorIdStringYour internal user ID for the person who created this invitation
invitationTypeInvitationTypeType of invitation: PERSONAL (1:1) or BROADCAST (1:many)
modifiedAtStringISO 8601 timestamp of last modification
statusInvitationStatusCurrent status: CREATED, DELIVERED, CLICKED, ACCEPTED, or EXPIRED
targetList&lt;InvitationTarget&gt;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&lt;InvitationScope&gt;Scopes (teams/orgs) this invitation grants access to
acceptsList&lt;InvitationAcceptance&gt;List of acceptance records if the invitation was accepted (optional, may be null)
scopeStringPrimary scope identifier (e.g., “team-123”)
scopeTypeStringType of the primary scope (e.g., “team”, “organization”)
expiredbooleanWhether this invitation has passed its expiration date
expiresStringISO 8601 timestamp when this invitation expires
passThroughStringPass-through data returned unchanged in webhooks and callbacks
sourceStringSource identifier for tracking (e.g., “ios-app”, “web-dashboard”)
subtypeStringSubtype for analytics segmentation (e.g., “pymk”, “find-friends”)
creatorNameStringDisplay name of the user who created this invitation
creatorAvatarUrlStringAvatar URL of the user who created this invitation

InvitationTarget

FieldTypeRequiredDescription
typeInvitationTargetTypeDelivery channel: EMAIL, PHONE, SHARE (link), or INTERNAL (in-app)
valueStringTarget address: email, phone number with country code, or share link ID
nameStringDisplay name of the recipient (e.g., “John Doe”)
avatarUrlStringAvatar URL for the recipient, shown in invitation lists and widgets

InvitationScope

Represents a group associated with an invitation. This matches the MemberGroups table structure from the API response.
FieldTypeRequiredDescription
idStringVortex internal UUID
accountIdStringVortex account ID
groupIdStringCustomer’s group ID (the ID they provided to Vortex)
typeStringGroup type (e.g., “workspace”, “team”)
nameStringGroup name
createdAtStringISO 8601 timestamp when the group was created

AutojoinDomain

Represents an autojoin domain - users with matching email domains automatically join the scope
FieldTypeRequiredDescription
idStringUnique identifier for this autojoin configuration
domainStringEmail domain that triggers autojoin (e.g., “acme.com”)

CreateInvitationScope

FieldTypeRequiredDescription
typeStringScope type (e.g., “team”, “organization”, “workspace”)
groupIdStringYour internal scope/group identifier
nameStringDisplay name shown to invitees (e.g., “Engineering Team”)

CreateInvitationTarget

FieldTypeRequiredDescription
typeCreateInvitationTargetTypeDelivery channel: EMAIL, PHONE, SHARE (link), or INTERNAL (in-app)
valueStringTarget address: email, phone number (with country code), or internal user ID
nameStringDisplay name of the recipient (shown in invitation emails and UI)
avatarUrlStringAvatar URL for the recipient (displayed in invitation lists)

Group

FieldTypeRequiredDescription
typeStringScope type (e.g., “team”, “organization”, “workspace”)
idStringLegacy scope identifier. Use scopeId instead.
scopeStringYour internal scope/group identifier (preferred over id)
nameStringDisplay name for the scope (e.g., “Engineering Team”)

Identifier

Represents an identifier for a user - used in JWT generation to link user across channels
FieldTypeRequiredDescription
typeStringIdentifier type: “email”, “phone”, “username”, or custom type
valueStringThe identifier value (email address, phone number, etc.)

InvitationAcceptance

FieldTypeRequiredDescription
idStringUnique identifier for this acceptance record
accountIdStringYour Vortex account ID
acceptedAtStringISO 8601 timestamp when the invitation was accepted
targetTypeStringHow the recipient was identified: “email” or “phone”
targetValueStringThe email or phone number of the person who accepted

Inviter

FieldTypeRequiredDescription
userIdStringYour internal user ID for the inviter (required for attribution)
userEmailStringInviter’s email address (used for reply-to and identification)
nameStringDisplay name shown to recipients (e.g., “John invited you to…”)
avatarUrlStringAvatar URL displayed in invitation emails and widgets

JWTPayload

FieldTypeRequiredDescription
userIdStringYour internal user ID (required - used for invitation attribution)
userEmailStringUser’s email address (preferred format for user identification)
userIsAutojoinAdminBooleanWhether user can manage autojoin settings for their scopes
identifiersList&lt;Identifier&gt;Legacy: List of user identifiers. Use userEmail instead.
groupsList&lt;Group&gt;Legacy: List of groups/scopes. Use scope parameter in generateToken instead.
roleStringLegacy: User role. No longer used.

UnfurlConfig

FieldTypeRequiredDescription
titleStringThe title shown in link previews (og:title)
descriptionStringThe description shown in link previews (og:description)
imageStringThe image URL shown in link previews (og:image) - must be HTTPS
typeStringThe Open Graph type (og:type) - e.g., ‘website’, ‘article’, ‘product’
siteNameStringThe site name shown in link previews (og:site_name)

User

FieldTypeRequiredDescription
idStringYour internal user ID (required for invitation attribution)
emailStringUser’s email address (used for identification and reply-to)
nameStringDisplay name shown to recipients (e.g., “John invited you”)
avatarUrlStringAvatar URL displayed in invitation emails and widgets (must be HTTPS)
adminScopesList&lt;String&gt;List of scopes where user has admin privileges (e.g., [“autojoin”])
allowedEmailDomainsList&lt;String&gt;Restrict invitations to these email domains (e.g., [“acme.com”])

VortexAnalyticsEvent

FieldTypeRequiredDescription
idStringUnique identifier for this analytics event
nameStringEvent name (e.g., “widget.opened”, “invite.sent”, “link.clicked”)
accountIdStringYour Vortex account ID
organizationIdStringOrganization ID if using multi-org setup
projectIdStringProject ID the event belongs to
environmentIdStringEnvironment ID (production, staging, etc.)
deploymentIdStringDeployment ID the event is associated with
widgetConfigurationIdStringWidget configuration ID that generated this event
foreignUserIdStringYour internal user ID who triggered the event
sessionIdStringClient session ID for grouping related events
platformStringPlatform: “web”, “ios”, “android”, “react-native”
segmentationStringA/B test segmentation identifier
timestampStringISO 8601 timestamp when the event occurred

VortexWebhookEvent

FieldTypeRequiredDescription
idStringUnique identifier for this webhook event
typeStringEvent type (e.g., “invitation.accepted”, “member.created”)
timestampStringISO 8601 timestamp when the event occurred
accountIdStringYour Vortex account ID
environmentIdStringEnvironment ID (production, staging, etc.)
sourceTableStringInternal: database table that triggered this event
operationStringDatabase operation: “INSERT”, “UPDATE”, or “DELETE”

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

  1. Go to your Vortex dashboard → Integrations → Webhooks tab
  2. Click “Add Webhook”
  3. Enter your endpoint URL (must be HTTPS in production)
  4. Copy the signing secret — you’ll use this to verify webhook signatures
  5. Select which events you want to receive

Example

Spring Boot webhook handler
import com.vortexsoftware.sdk.VortexWebhooks;
import org.springframework.web.bind.annotation.*;

@RestController
public class WebhookController {
    private final VortexWebhooks webhooks = new VortexWebhooks(
        System.getenv("VORTEX_WEBHOOK_SECRET")
    );

    @PostMapping("/webhooks/vortex")
    public Map<String, Object> handleWebhook(
        @RequestBody String body,
        @RequestHeader("X-Vortex-Signature") String signature
    ) {
        try {
            // Verify the signature
            if (!webhooks.verifySignature(body, signature)) {
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid signature");
            }

            // Parse the event
            WebhookEvent event = webhooks.parseEvent(body);

            switch (event.getType()) {
                case "invitation.accepted":
                    // User accepted an invitation — activate their account
                    System.out.println("Accepted: " + event.getData().getTargetEmail());
                    break;
                case "member.created":
                    // New member joined via invitation
                    System.out.println("New member: " + event.getData());
                    break;
            }

            return Map.of("received", true);
        } catch (Exception e) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Webhook error");
        }
    }
}

Events

EventDescription
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

ErrorDescription
VortexWebhookSignatureExceptionThrown when webhook signature verification fails. Check that you are using the raw request body and the correct signing secret.
VortexExceptionThrown for validation errors (e.g., missing API key, invalid parameters) or API failures

Resources