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
composer require teamvortexsoftware/vortex-php-sdk
Quick Start
Generate a secure token for Vortex components
<? php
use TeamVortexSoftware\VortexSDK\ VortexClient ;
$client = new VortexClient ( getenv ( 'VORTEX_API_KEY' ));
// Generate a token for the current user
$token = $client -> generateToken ([
'user' => [ 'id' => 'user-123' , 'email' => 'user@example.com' ]
]);
// Pass the token to your frontend component
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 PHP project composer require teamvortexsoftware / vortex - php - sdk
Initialize the client
Create a Vortex client with your API key (keep this on the server!) <? php
use TeamVortexSoftware\VortexSDK\ VortexClient ;
$client = new VortexClient ( getenv ( '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 $token = $client -> generateToken ([
'user' => [ 'id' => $currentUser -> id ]
]);
Pass the token to your frontend
Include the token in your page response or API response return response () -> json ([ '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(array $payload, ?array $options = null): string
Parameters:
Name Type Required Description payloadarray✓ Data to sign (user, component, scope, vars, etc.) options`array null` ✓ Optional configuration (expiresIn)
Returns: string — Signed JWT token
$vortex = new VortexClient($_ENV['VORTEX_API_KEY']);
$token = $vortex->generateToken(['user' => ['id' => 'user-123']]);
$token = $vortex->generateToken([
'component' => 'widget-abc',
'user' => ['id' => 'user-123', 'name' => 'Peter'],
'scope' => 'workspace_456',
'vars' => ['company_name' => 'Acme']
]);
$token = $vortex->generateToken(
['user' => ['id' => 'user-123']],
['expiresIn' => '1h'] // or 3600 for seconds
);
public function generateToken(array $payload, ?array $options = null): string
getInvitation()
Get a specific invitation by ID public function getInvitation(string $invitationId): array
getInvitation(string $invitationId): array
Parameters:
Name Type Required Description invitationIdstring✓ The invitation ID
Returns: array — The invitation data
acceptInvitation()
Accept a single invitation (recommended method) This is the recommended method for accepting invitations.
acceptInvitation(string $invitationId, array $user): array
Parameters:
Name Type Required Description invitationIdstring✓ Single invitation ID to accept userarray✓ User array with ‘email’/‘phone’/‘name’ keys
Returns: array — The accepted invitation result
$user = ['email' => 'user@example.com', 'name' => 'John Doe'];
$result = $client->acceptInvitation('inv-123', $user);
public function acceptInvitation(string $invitationId, array $user): array
getInvitationsByTarget()Get invitations by target (email or sms) public function getInvitationsByTarget(string t a r g e t T y p e , s t r i n g targetType, string t a r g e tT y p e , s t r in g targetValue): array getInvitationsByTarget(string $targetType, string $targetValue): array
Parameters: Name Type Required Description targetTypestring✓ Type of target (‘email’ or ‘phone’) targetValuestring✓ Target value (email address or phone number)
Returns: array — List of invitationsrevokeInvitation()Revoke (delete) an invitation public function revokeInvitation(string $invitationId): array revokeInvitation(string $invitationId): array
Parameters: Name Type Required Description invitationIdstring✓ The invitation ID to revoke
Returns: array — Success responseacceptInvitations()Accept multiple invitations Supports three formats: 1. User array (preferred): [‘email’ => ’…’, ‘phone’ => ’…’, ‘name’ => ’…’] 2. Target array (deprecated): [‘type’ => ‘email’, ‘value’ => ’…’] 3. Array of targets (deprecated): [[‘type’ => ‘email’, ‘value’ => ’…’], …] acceptInvitations(array $invitationIds, array $userOrTarget): array
Parameters: Name Type Required Description invitationIdsarray✓ List of invitation IDs to accept userOrTargetarray✓ User array with ‘email’/‘phone’/‘name’ keys, OR legacy target(s)
Returns: array — The accepted invitation result
$user = ['email' => 'user@example.com', 'name' => 'John Doe'];
$result = $client->acceptInvitations(['inv-123'], $user);
$target = ['type' => 'email', 'value' => 'user@example.com'];
$result = $client->acceptInvitations(['inv-123'], $target);
public function acceptInvitations(array $invitationIds, array $userOrTarget): array
deleteInvitationsByScope()Delete all invitations for a specific group public function deleteInvitationsByScope(string s c o p e T y p e , s t r i n g scopeType, string sco p e T y p e , s t r in g scope): array deleteInvitationsByScope(string $scopeType, string $scope): array
Parameters: Name Type Required Description scopeTypestring✓ The group type scopestring✓ The group ID
Returns: array — Success responsegetInvitationsByScope()Get all invitations for a specific group public function getInvitationsByScope(string s c o p e T y p e , s t r i n g scopeType, string sco p e T y p e , s t r in g scope): array getInvitationsByScope(string $scopeType, string $scope): array
Parameters: Name Type Required Description scopeTypestring✓ The group type scopestring✓ The group ID
Returns: array — List of invitations for the groupreinvite()Reinvite a user (send invitation again) public function reinvite(string $invitationId): array reinvite(string $invitationId): array
Parameters: Name Type Required Description invitationIdstring✓ The invitation ID to reinvite
Returns: array — The reinvited invitation resultgetAutojoinDomains()Get autojoin domains configured for a specific scope getAutojoinDomains(string $scopeType, string $scope): array
Parameters: Name Type Required Description scopeTypestring✓ The type of scope (e.g., “organization”, “team”, “project”) scopestring✓ The scope identifier (customer’s group ID)
Returns: array — Response with ‘autojoinDomains’ array and ‘invitation’
$result = $client->getAutojoinDomains('organization', 'acme-org');
foreach ($result['autojoinDomains'] as $domain) {
echo "Domain: " . $domain['domain'] . "\n";
}
public function getAutojoinDomains(string $scopeType, string $scope): array
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(
string $scope,
string $scopeType,
array $domains,
string $componentId,
?string $scopeName = null,
?array $metadata = null
): array
Parameters: Name Type Required Description scopestring✓ The scope identifier (customer’s group ID) scopeTypestring✓ The type of scope (e.g., “organization”, “team”) domainsarray✓ Array of domain strings to configure for autojoin componentIdstring✓ The component ID scopeName`string null` ✓ Optional display name for the scope metadata`array null` ✓ Optional metadata to attach to the invitation
Returns: array — Response with ‘autojoinDomains’ array and ‘invitation’
$result = $client->configureAutojoin(
'acme-org',
'organization',
['acme.com', 'acme.org'],
'component-123',
'Acme Corporation'
);
public function configureAutojoin(
string $scope,
string $scopeType,
array $domains,
string $componentId,
?string $scopeName = null,
?array $metadata = null
): array
Types
GenerateTokenPayloadPayload for generateToken() - used to generate secure tokens for Vortex components Field Type Required Description userTokenUserThe authenticated user who will be using the Vortex component componentstringComponent ID to generate token for (from your Vortex dashboard) scopestringScope identifier to restrict invitations (format: “scopeType:scopeId”) varsarrayCustom variables to pass to the component for template rendering
TokenUserUser data for token generation - represents the authenticated user sending invitations Field Type Required Description idstring✓ Unique identifier for the user in your system. Used to attribute invitations. emailstringUser’s email address. Used for reply-to in invitation emails. namestringDisplay name shown to invitation recipients (e.g., “John invited you”) avatarUrlstringURL to user’s avatar image. Displayed in invitation emails and widgets. adminScopesstring[]List of scope IDs where this user has admin privileges allowedEmailDomainsstring[]Restrict invitations to specific email domains (e.g., [“acme.com”])
AcceptUserUser data for accepting invitations - identifies who accepted the invitation Field Type Required Description emailstringEmail address of the accepting user. At least one of email or phone is required. phonestringPhone number with country code. At least one of email or phone is required. namestringDisplay name of the accepting user (shown in notifications to inviter) isExistingboolWhether user was already registered. true=existing, false=new signup, null=unknown.
CreateInvitationTargetTarget specification when creating an invitation - where to send the invite Field Type Required Description typestring✓ Delivery channel: “email”, “phone”, “share”, or “internal” valuestring✓ Target address: email address, phone number with country code, or internal user ID namestringDisplay name of the recipient (used in email greetings)
CreateInvitationScopeScope specification when creating an invitation - what group/team to invite into Field Type Required Description typestring✓ Scope type (e.g., “team”, “organization”, “workspace”) groupIdstring✓ Your internal identifier for this scope/group namestring✓ Display name for the scope (shown in invitation emails)
IdentifierEmail or phone identifier for looking up users Field Type Required Description typestring✓ Identifier type: “email” or “phone” valuestring✓ The email address or phone number (with country code for phone)
Request to configure autojoin domains for a scope Field Type Required Description scopeTypestring✓ Type of scope (e.g., “team”, “workspace”) scopeIdstring✓ Your internal identifier for the scope domainsstring[]✓ List of email domains to enable autojoin for (e.g., [“acme.com”])
SyncInternalInvitationRequestRequest to sync an internal invitation (for tracking invitations made outside Vortex) Field Type Required Description inviterIdstring✓ Your internal user ID for the person who sent the invitation targetCreateInvitationTarget✓ The invitation recipient scopesCreateInvitationScope[]Scopes/groups the invitation grants access to
InvitationResultComplete invitation details as returned by the Vortex API Field Type Required Description idstring✓ Unique identifier for this invitation accountIdstring✓ Your Vortex account ID clickThroughsint✓ Number of times the invitation link was clicked formSubmissionData`array null` Invitation form data submitted by the user, including invitee identifiers (such as email addresses, phone numbers, or internal IDs) and the values of any custom fields. configurationAttributes`array null` Deprecated: Use formSubmissionData instead. Contains the same data. createdAtstring✓ ISO 8601 timestamp when the invitation was created deactivatedbool✓ Whether this invitation has been revoked or expired deliveryCountint✓ Number of times the invitation was sent (including reminders) deliveryTypesstring[]✓ Channels used to deliver: “email”, “phone”, “share”, “internal” foreignCreatorIdstring✓ Your internal user ID for the person who created this invitation invitationTypestring✓ Type: “single_use”, “multi_use”, or “autojoin” statusstring✓ Current status: queued, sending, sent, delivered, accepted, shared targetInvitationTarget[]✓ List of invitation recipients with their contact info and status viewsint✓ Number of times the invitation page was viewed groupsInvitationScope[]✓ Scopes (teams/orgs) this invitation grants access to expiredbool✓ Whether this invitation has passed its expiration date expiresstringISO 8601 timestamp when this invitation expires inviterInviterInformation about who sent the invitation
InvitationTargetTarget recipient of an invitation (from API response) Field Type Required Description typestring✓ Delivery channel: “email”, “phone”, “share”, or “internal” valuestring✓ Target address: email, phone number with country code, or share link ID namestringDisplay name of the recipient avatarUrlstringAvatar URL for the recipient statusstringDelivery status for this specific target
InvitationScopeScope/group that the invitation grants access to (from API response) Field Type Required Description idstring✓ Vortex internal UUID for this scope record accountIdstring✓ Your Vortex account ID groupIdstring✓ Your internal scope/group identifier typestring✓ Scope type (e.g., “team”, “organization”, “workspace”) namestring✓ Display name for the scope createdAtstring✓ ISO 8601 timestamp when the scope was created
InvitationAcceptanceDetails about an invitation acceptance event Field Type Required Description idstring✓ Unique identifier for this acceptance record invitationIdstring✓ ID of the invitation that was accepted emailstringEmail of the user who accepted phonestringPhone of the user who accepted namestringName of the user who accepted isExistingboolWhether the user already had an account createdAtstring✓ ISO 8601 timestamp when the acceptance occurred
InviterInformation about the user who sent an invitation Field Type Required Description idstring✓ Your internal user ID for the inviter emailstringEmail address of the inviter namestringDisplay name of the inviter avatarUrlstringAvatar URL of the inviter
AutojoinDomainAutojoin domain configuration - users with matching email domains automatically join Field Type Required Description idstring✓ Unique identifier for this autojoin configuration domainstring✓ Email domain that triggers autojoin (e.g., “acme.com”)
AutojoinDomainsResponseResponse from getAutojoinDomains() Field Type Required Description domainsAutojoinDomain[]✓ List of configured autojoin domains
SyncInternalInvitationResponseResponse from syncInternalInvitation() Field Type Required Description invitationInvitationResult✓ The created or updated invitation createdbool✓ True if a new invitation was created, false if existing was updated
VortexWebhookEventWebhook event payload delivered to your endpoint Field Type Required Description idstring✓ Unique identifier for this webhook delivery typestring✓ Event type (e.g., “invitation.accepted”, “member.created”) timestampstring✓ ISO 8601 timestamp when the event occurred dataarray✓ Event-specific payload data
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
Laravel webhook handler
<?php
use TeamVortexSoftware\VortexSDK\VortexWebhooks;
use Illuminate\Http\Request;
class WebhookController extends Controller
{
public function handleVortex(Request $request)
{
$webhooks = new VortexWebhooks(env('VORTEX_WEBHOOK_SECRET'));
$payload = $request->getContent();
$signature = $request->header('X-Vortex-Signature');
// Verify the signature
if (!$webhooks->verifySignature($payload, $signature)) {
return response()->json(['error' => 'Invalid signature'], 400);
}
// Parse the event
$event = $webhooks->parseEvent($payload);
switch ($event['type']) {
case 'invitation.accepted':
// User accepted an invitation — activate their account
Log::info('Accepted: ' . json_encode($event['data']));
break;
case 'member.created':
// New member joined via invitation
Log::info('New member: ' . json_encode($event['data']));
break;
}
return response()->json(['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 VortexWebhookSignatureExceptionThrown when webhook signature verification fails. Check that you are using the raw request body and the correct signing secret. ExceptionThrown for validation errors (e.g., missing API key, invalid parameters)
Resources