Organization Invitations
Organization invitations enable you to onboard new members to your organization with pre-configured roles, permissions, and site access. The invitation system supports both authenticated (admin) and public (invitee) workflows.
Overview
The invitation system provides a secure way to:
- Invite new users to join your organization via email
- Pre-configure user roles and permissions before acceptance
- Grant access to specific sites with custom permissions
- Track invitation status and manage pending invitations
- Allow invitees to accept invitations without prior authentication
Key Features
Flexible Permission Setup
- Assign users to groups automatically upon acceptance
- Grant site-specific permissions
- Configure access levels before the user joins
Secure Public Access
- Invitees can view and accept invitations without authentication
- Unique, secure invitation tokens prevent unauthorized access
- One-time use tokens prevent duplicate acceptances
Email Integration
- Automatic invitation emails with acceptance links
- Customizable email templates
- Resend functionality for expired or lost invitations (by invitee user ID)
- Email subject and body can differ when the invitee email already belongs to an existing platform user (sign-in wording) versus a newly created inactive user (first-time setup wording). This is determined server-side from the user lookup; clients do not send a separate flag, and invitation API responses omit internal email-delivery metadata.
For Organization Admins
Creating Invitations
Send an invitation to a new member with optional group and site access configuration.
Endpoint:
POST /api/cloud/organizations/{org_slug}/invitations/
Authentication: Required (Bearer token)
Request Body:
{
"invitee_identifier": "user@example.com",
"invitation_config": {
"group": ["Developers", "Admins"],
"site": [
{
"slug": "my-site",
"permissions": ["view_site", "manage_site"]
},
{
"slug": "another-site",
"permissions": ["view_site"]
}
]
}
}
Parameters:
invitee_identifier(required): Email address of the person to inviteinvitation_config(optional): Configuration for member setupgroup: Array of group names to assign the user tosite: Array of site configurations with slug and permissions
Example:
- REST API
- Python
- JavaScript
curl -X POST "https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"invitee_identifier": "newuser@acme.com",
"invitation_config": {
"group": ["Developers"],
"site": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
}
]
}
}'
Response: 201 Created
{
"id": 1,
"uuid": "6cd09cc9-1724-4371-8c6f-336eba61e46e",
"organization": 1,
"organization_name": "Acme Corporation",
"invitee_identifier": "newuser@acme.com",
"invited_by": 1,
"invited_by_user": {
"id": 1,
"uuid": "1b3c4d93-e058-457f-85b8-0276dd4af5c4",
"username": "admin",
"email": "admin@acme.com",
"first_name": "Admin",
"last_name": "User"
},
"invitee": null,
"invitee_user": null,
"config": {
"group": ["Developers"],
"site": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
}
]
},
"created": "2025-11-18T10:00:00Z"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/",
headers=headers,
json={
"invitee_identifier": "newuser@acme.com",
"invitation_config": {
"group": ["Developers"],
"site": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
}
]
}
}
)
data = response.json()
const response = await fetch("https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
invitee_identifier: "newuser@acme.com",
invitation_config: {
group: ["Developers"],
site: [
{
slug: "production-site",
permissions: ["view_site", "manage_site"]
}
]
}
})
})
const data = await response.json()
An invitation email is automatically sent to the invitee with a secure acceptance link.
Listing Invitations
View all pending invitations for your organization.
Endpoint:
GET /api/cloud/organizations/{org_slug}/invitations/
Authentication: Required (Bearer token)
Query Parameters:
invitee__is_active: Filter by invitee user active statusfalse: Pending invitations (user hasn't accepted yet)true: Accepted invitations (user is active)
search: Search by invitee emailordering: Sort bycreated,-createdpage: Page number for paginationpage_size: Number of results per page
Examples:
# Get pending invitations (not yet accepted)
GET /api/cloud/organizations/acme-corp/invitations/?invitee__is_active=false
# Get accepted invitations
GET /api/cloud/organizations/acme-corp/invitations/?invitee__is_active=true
# Search and paginate
GET /api/cloud/organizations/acme-corp/invitations/?search=john&page=1&page_size=10
Example:
- REST API
- Python
- JavaScript
curl -X GET "https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/?invitee__is_active=false" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response: 200 OK
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"uuid": "6cd09cc9-1724-4371-8c6f-336eba61e46e",
"organization": 1,
"organization_name": "Acme Corporation",
"invitee_identifier": "newuser@acme.com",
"invited_by": 1,
"config": {
"group": ["Developers"],
"site": [...]
},
"created": "2025-11-18T10:00:00Z"
}
]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/",
headers=headers
)
data = response.json()
const response = await fetch("https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Resending Invitations
Resend the invitation email if the original was lost or expired. The endpoint uses the invitee's user ID to look up the most recent pending invitation.
Endpoint:
POST /api/cloud/organizations/{org_slug}/invitations/{user_id}/resend/
Authentication: Required (Bearer token)
Path Parameters:
user_id(required): The invitee's user ID
Example:
- REST API
- Python
- JavaScript
curl -X POST "https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/5/resend/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response: 200 OK
{
"status": "success",
"message": "Invitation resent successfully"
}
Error Response: 400 Bad Request
{
"user_id": "No pending invitation found for this user."
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.post(
"https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/5/resend/",
headers=headers
)
data = response.json()
const response = await fetch("https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/5/resend/", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
If multiple invitations exist for the same user, the most recently created one is resent.
Deleting Invitations
Cancel a pending invitation.
Endpoint:
DELETE /api/cloud/organizations/{org_slug}/invitations/{uuid}/
Authentication: Required (Bearer token)
Example:
- REST API
- Python
- JavaScript
curl -X DELETE "https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response: 204 No Content
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.delete(
"https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/",
headers=headers
)
const response = await fetch("https://api.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
For Invitees (Public Access)
Viewing Invitation Details
View invitation details before accepting (no authentication required).
Endpoint:
GET /api/cloud/invitations/{token}/details/
Authentication: None (Public endpoint)
Example:
- REST API
- Python
- JavaScript
curl -X GET "https://api.taruvi.cloud/api/cloud/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/details/"
Response: 200 OK
{
"id": 1,
"uuid": "6cd09cc9-1724-4371-8c6f-336eba61e46e",
"organization": 1,
"organization_name": "Acme Corporation",
"invitee_identifier": "newuser@acme.com",
"invited_by": 1,
"invited_by_user": {
"id": 1,
"username": "admin",
"email": "admin@acme.com",
"first_name": "Admin",
"last_name": "User"
},
"config": {
"group": ["Developers"],
"site": [...]
},
"created": "2025-11-18T10:00:00Z"
}
Error Responses:
404 Not Found: Invalid invitation token410 Gone: Invitation already accepted
import requests
response = requests.get(
"https://api.taruvi.cloud/api/cloud/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/details/"
)
data = response.json()
const response = await fetch("https://api.taruvi.cloud/api/cloud/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/details/")
const data = await response.json()
Accepting Invitations
Accept an invitation and create/activate your user account (no authentication required).
Endpoint:
POST /api/cloud/invitations/{token}/accept/
Authentication: None (Public endpoint)
Request Body:
{
"password": "SecurePassword123!",
"first_name": "John",
"last_name": "Doe"
}
Parameters:
password(required): Password for your new accountfirst_name(required): Your first namelast_name(required): Your last name
Example:
- REST API
- Python
- JavaScript
curl -X POST "https://api.taruvi.cloud/api/cloud/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/accept/" \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123!",
"first_name": "John",
"last_name": "Doe"
}'
Response: 200 OK
{
"success": true,
"message": "Invitation accepted successfully",
"user": {
"id": 5,
"email": "newuser@acme.com",
"first_name": "John",
"last_name": "Doe"
},
"organization": {
"id": 1,
"slug": "acme-corp",
"name": "Acme Corporation"
}
}
import requests
headers = {"Content-Type": "application/json"}
response = requests.post(
"https://api.taruvi.cloud/api/cloud/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/accept/",
headers=headers,
json={
"password": "SecurePassword123!",
"first_name": "John",
"last_name": "Doe"
}
)
data = response.json()
const response = await fetch("https://api.taruvi.cloud/api/cloud/invitations/6cd09cc9-1724-4371-8c6f-336eba61e46e/accept/", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
password: "SecurePassword123!",
first_name: "John",
last_name: "Doe"
})
})
const data = await response.json()
What Happens:
- User account is created (or activated if it exists)
- Password is set for the account
- User is added to the organization
- Groups are assigned automatically
- Site permissions are granted
- Invitation is marked as used (cannot be accepted again)
Error Responses:
400 Bad Request: Missing or invalid password/name404 Not Found: Invalid invitation token410 Gone: Invitation already accepted
After accepting an invitation, you can immediately log in using the email and password you provided.
Invitation Workflow
Standard Flow
Step-by-Step
-
Admin creates invitation
- Specifies invitee email
- Configures groups and site permissions
- Receives invitation UUID
-
System processes invitation
- Creates placeholder user (inactive)
- Stores configuration
- Sends invitation email
-
Invitee receives email
- Gets unique invitation link
- Link contains secure token
-
Invitee views details (optional)
- Sees organization name
- Sees who invited them
- Reviews access they'll receive
-
Invitee accepts invitation
- Provides password and name
- Account is activated
- Groups and permissions applied automatically
-
Invitee can log in
- Uses email and password
- Has immediate access to organization and sites
Permission Configuration
Group Assignment
Groups define broad role-based access. Common group examples:
- Admin: Full organization management
- Member: Standard user access
- Viewer: Read-only access
- Developer: Site management access
Example:
{
"invitation_config": {
"group": ["Developers", "Admins"]
}
}
Group names can be obtained from the Groups API. Contact your organization admin for available groups.
Site Permissions
Grant granular access to specific sites within the organization.
Available Permissions:
access_site: Basic access to the siteview_site: Read-only access to the sitechange_site: Modify site settingsdelete_site: Delete the sitemanage_site: Full site managementmanage_site_users: Manage site user permissionsadmin_site: Full site administration
Example:
{
"invitation_config": {
"site": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
},
{
"slug": "staging-site",
"permissions": ["view_site"]
}
]
}
}
Site slugs must exist in the organization before the invitation is accepted. Invalid slugs are silently ignored.
Best Practices
For Admins
- Minimal Permissions: Only grant necessary permissions
- Group Strategy: Use groups for consistent role assignment
- Regular Cleanup: Delete or resend expired invitations
- Monitor Acceptance: Track which invitations are pending
- Audit Access: Review member permissions after acceptance
For Invitees
- Strong Passwords: Use secure passwords (min 8 characters, mixed case, numbers)
- Verify Organization: Check invitation details before accepting
- Contact Support: If invitation seems suspicious, verify with sender
- Save Credentials: Store your email and password securely
Security Features
Token-Based Access
- Invitations use UUID v4 tokens (128-bit randomness)
- Tokens are single-use and expire after acceptance
- No authentication required for acceptance (secure by obscurity)
Rate Limiting
- API endpoints are rate-limited to prevent abuse
- Failed attempts are logged and monitored
Email Verification
- Invitations are sent to the specified email address
- Only the recipient can access the invitation link
Audit Trail
- All invitation actions are logged
- Track who invited whom and when
- Monitor acceptance patterns
Common Use Cases
Onboarding Team Members
Invite new employees with pre-configured access to relevant sites and tools.
{
"invitee_identifier": "newemployee@company.com",
"invitation_config": {
"group": ["Developers"],
"site": [
{
"slug": "dev-environment",
"permissions": ["view_site", "manage_site"]
}
]
}
}
External Collaborators
Grant limited access to specific sites for contractors or partners.
{
"invitee_identifier": "contractor@external.com",
"invitation_config": {
"group": ["Guests"],
"site": [
{
"slug": "client-site",
"permissions": ["view_site"]
}
]
}
}
Multi-Site Access
Provide different permission levels across multiple sites.
{
"invitee_identifier": "manager@company.com",
"invitation_config": {
"group": ["Managers"],
"site": [
{
"slug": "site-a",
"permissions": ["manage_site"]
},
{
"slug": "site-b",
"permissions": ["view_site"]
}
]
}
}
Troubleshooting
Invitation Not Received
- Check spam/junk folders
- Verify email address is correct
- Use resend functionality
- Check organization email settings
Cannot Accept Invitation
- Ensure invitation hasn't been accepted already (check for 410 error)
- Verify invitation token in URL is complete
- Check password meets requirements
- Try a different browser
Wrong Permissions After Acceptance
- Verify invitation config was correct
- Check group membership in organization settings
- Contact organization admin to adjust permissions
- Review site-specific permissions
Email Already Exists
If the email is already registered:
- The existing account will be activated
- New password will override the old one
- User will be added to the new organization
- Previous organization memberships are retained
API Reference Summary
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/organizations/{slug}/invitations/ | POST | Required | Create invitation |
/organizations/{slug}/invitations/ | GET | Required | List invitations |
/organizations/{slug}/invitations/{uuid}/ | GET | Required | Get invitation details |
/organizations/{slug}/invitations/{uuid}/ | DELETE | Required | Cancel invitation |
/organizations/{slug}/invitations/{user_id}/resend/ | POST | Required | Resend invitation email |
/invitations/{token}/details/ | GET | Public | View invitation (invitee) |
/invitations/{token}/accept/ | POST | Public | Accept invitation (invitee) |
Related Documentation
- Organizations - Learn about organization management
- Users - User account management
- Groups - Role-based access control
- Permissions - Fine-grained permission system
- Sites - Multi-tenant site management