Organizations
Organizations are the top-level entities in Taruvi Cloud that group users, sites, and resources together. They provide a way to manage teams and their associated cloud environments.
All organization endpoints now use slug-based URLs (e.g., /api/cloud/organizations/acme-corp/) instead of UUID-based URLs. Slugs are human-readable, SEO-friendly identifiers automatically generated from the organization name. UUIDs are still supported for backward compatibility.
Overview
An organization represents a company, team, or any group of users working together. Each organization can have:
- Multiple members with different roles and permissions
- Multiple sites (cloud environments/tenants)
- Custom settings and configurations
- Invitations to onboard new members
Key Features
Multi-Tenant Structure
Organizations enable multi-tenant SaaS architecture where:
- Each organization is isolated from others
- Resources (sites, users, data) are scoped to organizations
- Cross-organization data access is prevented
Role-Based Access
Organizations support fine-grained permission management:
- Owner: Full control over the organization
- Members: Can be assigned specific permissions
- Custom Permissions:
view_organization,change_organization,delete_organization,manage_organization,invite_members
Member Management
- Add and remove members
- Assign permissions to members
- Track member activity and roles
- Invite new members via email
Using Organizations
Creating an Organization
To create a new organization:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"name": "Acme Corporation",
"slug": "acme-corp"
}'
Response (201 Created):
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Corporation",
"slug": "acme-corp",
"is_active": true,
"created": "2024-01-15T10:30:00Z",
"modified": "2024-01-15T10:30:00Z"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/",
headers=headers,
json={
"name": "Acme Corporation",
"slug": "acme-corp"
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "Acme Corporation",
slug: "acme-corp"
})
})
const data = await response.json()
Listing Organizations
Get all organizations you have access to:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Query Parameters:
search: Search by name or slugis_active: Filter by active statustrueor1: Only active organizations (default)falseor0: Only inactive organizationsallor*: All organizations regardless of status
ordering: Sort results (e.g.,name,-created,modified)
Retrieving Organization Details
Get details of a specific organization:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Updating an Organization
Update organization details:
- REST API
- Python
- JavaScript
curl -X PUT https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"name": "Acme Corporation Ltd",
"is_active": true
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.put(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/",
headers=headers,
json={
"name": "Acme Corporation Ltd",
"is_active": True
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "Acme Corporation Ltd",
is_active: true
})
})
const data = await response.json()
Deleting an Organization
Delete an organization permanently:
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/",
headers=headers
)
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
Organization deletion is permanent (hard delete) and triggers the following cascade:
- All organization memberships are removed
- All invitations are deleted
- All sites belonging only to this organization are deleted (including their PostgreSQL schemas)
- All domains linked to those sites are deleted
- All Guardian permissions for the organization are removed
- Users who are not members of any other organization are soft-deleted (marked inactive)
Managing Members
Adding Members
Add a user to an organization:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"user_slug": "jane-smith"
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers,
json={"user_slug": "jane-smith"}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ user_slug: "jane-smith" })
})
const data = await response.json()
Listing Members
Get all members of an organization:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Retrieving Member Details
Get details of a specific member including their groups and site permissions:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK):
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"username": "john.doe",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"is_active": true,
"is_admin": false,
"is_owner": false,
"groups": [
{
"id": 1,
"name": "Developers"
}
],
"sites": [
{
"uuid": "750e8400-e29b-41d4-a716-446655440000",
"name": "Production Site",
"schema_name": "production_site",
"permissions": ["access_site", "view_site", "manage_site"]
}
]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Updating Member Permissions
Update a member's groups and site permissions:
- REST API
- Python
- JavaScript
curl -X PUT https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"is_admin": false,
"groups": [1, 3],
"site": [
{
"uuid": "site-uuid",
"permissions": ["access_site", "manage_site"]
}
]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.put(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/",
headers=headers,
json={
"is_admin": False,
"groups": [1, 3],
"site": [
{
"uuid": "site-uuid",
"permissions": ["access_site", "manage_site"]
}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
is_admin: false,
groups: [1, 3],
site: [
{
uuid: "site-uuid",
permissions: ["access_site", "manage_site"]
}
]
})
})
const data = await response.json()
Managing Admin Status
Make a member an admin:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/make_admin/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/make_admin/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/make_admin/", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Remove admin status:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/remove_admin/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/remove_admin/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/remove_admin/", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
You cannot remove admin status from the last admin of an organization. There must always be at least one admin.
Removing Members
Remove a member from an organization:
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/jane.smith/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/jane.smith/",
headers=headers
)
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/jane.smith/", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
Checking Your Permissions
Get your effective permissions within an organization:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/privileges/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK):
{
"permissions": [
"view_organization",
"change_organization",
"manage_organization",
"invite_members",
"manage_sites"
]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/privileges/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/privileges/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
This endpoint returns all permissions you have on the specified organization, including permissions inherited from groups.
Managing Invitations
Invitations allow you to onboard new members to your organization with pre-configured access levels, groups, and site permissions.
Quick Start
Send a basic invitation:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"invitee_identifier": "[email protected]"
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/",
headers=headers,
json={"invitee_identifier": "[email protected]"}
)
data = response.json()
const response = await fetch("https://your-site.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: "[email protected]" })
})
const data = await response.json()
Send an invitation with permissions:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"invitee_identifier": "[email protected]",
"invitation_config": {
"group": [3],
"site": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
}
]
}
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/",
headers=headers,
json={
"invitee_identifier": "[email protected]",
"invitation_config": {
"group": [3],
"site": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
}
]
}
}
)
data = response.json()
const response = await fetch("https://your-site.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: "[email protected]",
invitation_config: {
group: [3],
site: [
{
slug: "production-site",
permissions: ["view_site", "manage_site"]
}
]
}
})
})
const data = await response.json()
What the invitation config does:
group: Assigns user to specified groups (by ID) upon acceptancesite: Grants site-specific permissions upon acceptance
Public Invitation URLs
Invitees can accept invitations without authentication using public URLs:
GET /api/cloud/invitations/{token}/details/ (View invitation)
POST /api/cloud/invitations/{token}/accept/ (Accept invitation)
These endpoints are unauthenticated and accessible by anyone with the invitation token.
For detailed invitation workflows, permission configuration, and public acceptance APIs, see the Invitations Guide.
Common Operations
List invitations:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Resend invitation email:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/{uuid}/resend/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/{uuid}/resend/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/{uuid}/resend/", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Delete invitation:
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/{uuid}/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/{uuid}/",
headers=headers
)
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/invitations/{uuid}/", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
Note: Invitations use UUID tokens for security. Once accepted, they cannot be reused.
Permissions
Organizations support the following permissions:
| Permission | Description |
|---|---|
view_organization | View organization details |
change_organization | Update organization settings |
delete_organization | Delete the organization |
manage_organization | Full management access (members, sites, settings) |
invite_members | Send invitations to new members |
Best Practices
- Unique Slugs: Use meaningful, unique slugs for easy identification
- Active Management: Keep
is_activestatus updated to control access - Permission Assignment: Grant minimum required permissions to members
- Regular Audits: Review member list and permissions regularly
- Soft Deletes: Consider deactivating organizations instead of deleting them
Use Cases
Multi-Company SaaS
Serve multiple companies, each with their own organization, isolated data, and team members.
Department Isolation
Create separate organizations for different departments within a company (e.g., Engineering, Marketing, Sales).
Client Management
Agencies can create organizations for each client, managing their sites and resources separately.
Partner Ecosystems
Enable partners to have their own organizations while maintaining platform-level control.
Related Features
- Invitations - Invite and onboard new members with pre-configured access
- Sites - Create isolated cloud environments within organizations
- User Management - Manage organization members
- Groups - Organize members into groups with shared permissions
- Permissions - Fine-grained access control system