vortex-ruby-sdk
Invitation infrastructure for modern apps
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. Learn more about Vortex →
Why This SDK?
This backend SDK securely signs user data for Vortex components. Your API key stays on your server, while the signed token is passed to the frontend where Vortex components render the invitation UI.
- Keep your API key secure — it never touches the browser
- Sign user identity for attribution — know who sent each invitation
- Control what data components can access via scoped tokens
- Verify webhook signatures for secure event handling
How It Works
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.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Your Server │ │ User Browser │ │ Vortex Cloud │
│ (this SDK) │ │ (component) │ │ │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ 1. generate_token │ │
│◄──────────────────────│ │
│ │ │
│ 2. Return token │ │
│──────────────────────►│ │
│ │ │
│ │ 3. Component calls │
│ │ API with token │
│ │──────────────────────►│
│ │ │
│ │ 4. Render UI, │
│ │ send invitations │
│ │◄──────────────────────│
│ │ │
Integration Flow
1. Install the backend SDK [backend]
Add this SDK to your Ruby project
gem 'vortex-ruby-sdk'
2. Initialize the client [backend]
Create a Vortex client with your API key (keep this on the server!)
require 'vortex'
client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
3. Generate a token for the current user [backend]
When a user loads a page with a Vortex component, generate a signed token on your server
token = client.generate_token(user: { id: current_user.id })
4. Pass the token to your frontend [backend]
Include the token in your page response or API response
render json: { vortex_token: token }
5. Render a Vortex component with the token [frontend]
Use the React/Angular/Web Component with the token
import { VortexInvite } from "@teamvortexsoftware/vortex-react";
<VortexInvite token={vortexToken} />
6. Vortex handles the rest [vortex]
The component securely communicates with Vortex servers, displays the invitation UI, sends emails/SMS, tracks conversions, and reports analytics
Security Model
⚠️ Important: Your Vortex API key is a secret that grants full access to your account. It must never be exposed to browsers or client-side code.
By signing tokens on your server, you:
- Keep your API key secret (it never leaves your server)
- Control exactly what user data is shared with components
- Ensure invitations are attributed to real, authenticated users
- Prevent abuse — users can only send invitations as themselves
When Signing is Optional
Token signing is controlled by your component configuration in the Vortex dashboard. If "Require Secure Token" is enabled, requests without a valid token will be rejected. If disabled (e.g., for public referral programs), components work without backend signing.
Quick Start
Generate a secure token for Vortex components
require 'vortex'
client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
# Generate a token for the current user
token = client.generate_token(user: { id: 'user-123', email: 'user@example.com' })
# Pass the token to your frontend component
Installation
gem install vortex-ruby-sdk
Initialization
client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
Environment Variables
| Variable | Required | Description |
|---|---|---|
VORTEX_API_KEY |
✓ | Your Vortex API key |
Core Methods
These are the methods you'll use most often.
generate_token()
Generate a signed token 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.
Signature:
generate_token(payload, = nil)
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
payload |
Hash |
✓ | Data to sign (user, component, scope, vars, etc.) |
options |
Hash |
✓ | Optional configuration |
Returns: String
— Signed JWT token
Example:
# token = client.generate_token({ user: { id: 'user-123' } })
#
# token = client.generate_token({
# component: 'widget-abc',
# user: { id: 'user-123', name: 'Peter', email: 'peter@example.com' },
# scope: 'workspace_456',
# vars: { company_name: 'Acme' }
# })
#
# token = client.generate_token(payload, { expires_in: '1h' })
# token = client.generate_token(payload, { expires_in: 3600 }) # seconds
Added in v0.8.0
get_invitation()
Get a specific invitation by ID
Signature:
get_invitation(invitation_id)
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
invitation_id |
String |
✓ | The invitation ID |
Returns: String
— The invitation data
Added in v0.1.0
accept_invitation()
Accept a single invitation (recommended method) This is the recommended method for accepting invitations.
Signature:
accept_invitation(invitation_id, user)
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
invitation_id |
String |
✓ | Single invitation ID to accept |
user |
Hash |
✓ | User hash with :email and/or :phone |
Returns: String
— The accepted invitation result
Example:
# user = { email: 'user@example.com', name: 'John Doe' }
# result = client.accept_invitation('inv-123', user)
Added in v0.6.0
All Methods
Click to expand full method reference
### `get_invitations_by_target()` Get invitations by target **Signature:** ```ruby get_invitations_by_target(target_type, target_value) ``` **Parameters:** | Name | Type | Required | Description | | -------------- | -------- | -------- | --------------------------------------------- | | `target_type` | `String` | ✓ | Type of target (email, sms) | | `target_value` | `String` | ✓ | Value of target (email address, phone number) | **Returns:** `String` — List of invitations _Added in v0.1.0_ --- ### `revoke_invitation()` Revoke (delete) an invitation **Signature:** ```ruby revoke_invitation(invitation_id) ``` **Parameters:** | Name | Type | Required | Description | | --------------- | -------- | -------- | --------------------------- | | `invitation_id` | `String` | ✓ | The invitation ID to revoke | **Returns:** `String` — Success response _Added in v0.1.0_ --- ### `accept_invitations()` Accept invitations using the new User format (preferred) Supports three formats: 1. User hash (preferred): { email: '...', phone: '...', name: '...' } 2. Target hash (deprecated): { type: 'email', value: '...' } 3. Array of targets (deprecated): [{ type: 'email', value: '...' }, ...] **Signature:** ```ruby accept_invitations(invitation_ids, user_or_target) ``` **Parameters:** | Name | Type | Required | Description | | ---------------- | --------------- | -------- | ------------------------------------------------------------ | | `invitation_ids` | `ArrayTypes
Click to expand type definitions
### `GenerateTokenPayload` Payload for generate_token() - used to generate secure tokens for Vortex components | Field | Type | Required | Description | | ----------- | ------------------ | -------- | ---------------------------------------------------------------------- | | `user` | `Hash (TokenUser)` | | The authenticated user who will be using the Vortex component | | `component` | `String` | | Component ID to generate token for (from your Vortex dashboard) | | `scope` | `String` | | Scope identifier to restrict invitations (format: "scopeType:scopeId") | | `vars` | `Hash` | | Custom variables to pass to the component for template rendering | ### `TokenUser` User data for token generation - represents the authenticated user sending invitations | Field | Type | Required | Description | | ----------------------- | --------------- | -------- | ----------------------------------------------------------------------------- | | `id` | `String` | ✓ | Unique identifier for the user in your system. Used to attribute invitations. | | `email` | `String` | | User's email address. Used for reply-to in invitation emails. | | `name` | `String` | | Display name shown to invitation recipients (e.g., "John invited you") | | `avatar_url` | `String` | | URL to user's avatar image. Displayed in invitation emails and widgets. | | `admin_scopes` | `ArrayWebhooks
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
Verifying Webhooks
Always verify webhook signatures using Vortex::Webhooks.verify_signature() to ensure requests are from Vortex.
The signature is sent in the X-Vortex-Signature header.
Example: Rails webhook handler
class WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def vortex
webhooks = Vortex::Webhooks.new(ENV['VORTEX_WEBHOOK_SECRET'])
payload = request.raw_post
signature = request.headers['X-Vortex-Signature']
# Verify the signature
unless webhooks.verify_signature(payload, signature)
return render json: { error: 'Invalid signature' }, status: 400
end
# Parse the event
event = webhooks.parse_event(payload)
case event['type']
when 'invitation.accepted'
# User accepted an invitation — activate their account
Rails.logger.info "Accepted: #{event['data']}"
when 'member.created'
# New member joined via invitation
Rails.logger.info "New member: #{event['data']}"
end
render json: { received: true }
end
end
Common 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.
Supported Events
| Event | Description |
|---|---|
invitation.created |
A new invitation was created |
invitation.accepted |
An invitation was accepted by the recipient |
invitation.deactivated |
An invitation was deactivated (revoked or expired) |
invitation.email.delivered |
Invitation email was successfully delivered |
invitation.email.bounced |
Invitation email bounced (invalid address) |
invitation.email.opened |
Recipient opened the invitation email |
invitation.link.clicked |
Recipient clicked the invitation link |
invitation.reminder.sent |
A reminder email was sent for a pending invitation |
member.created |
A new member was created from an accepted invitation |
group.member.added |
A member was added to a scope/group |
deployment.created |
A new deployment configuration was created |
deployment.deactivated |
A deployment was deactivated |
abtest.started |
An A/B test was started |
abtest.winner_declared |
An A/B test winner was declared |
email.complained |
Recipient marked the email as spam |
Error Handling
All SDK errors extend VortexError.
| Error | Description |
|---|---|
VortexError |
Raised for validation errors (e.g., missing API key, invalid parameters) or API failures |