Cloud Console API
The Cloud Console API provides a comprehensive system for managing multi-tenant cloud infrastructure. It follows a hierarchical structure: Organization → Sites → Domains with user management, groups, and permissions layered across.
All Cloud Console API endpoints use slug-based URLs (e.g., /api/organizations/acme-corp/, /api/sites/production-site/) instead of UUID-based URLs. Slugs are human-readable, SEO-friendly identifiers automatically generated from resource names. UUIDs are still supported for backward compatibility.
Overview
The Cloud Console API enables you to:
- Manage Organizations: Create and manage top-level organizational entities
- Deploy Sites: Isolated multi-tenant environments with schema-based isolation
- Configure Domains: Map custom domains to sites for multi-tenant routing
- User Management: Complete user lifecycle and access control
- Group Management: Organize users with role-based access
- Permission Control: Fine-grained object-level permissions
Architecture
Key Concepts
Organization
A top-level entity that groups users, sites, and resources together. Each organization represents a company, team, or any group working together.
- Slug-Based Access:
/api/organizations/{org-slug}/ - Multi-Tenant: Complete isolation between organizations
- Role-Based: Owners, members, and custom permissions
- Invitation System: Email-based member onboarding
Site (Tenant)
An isolated cloud environment with its own database schema. Sites provide complete data isolation using PostgreSQL schemas.
- Slug-Based Access:
/api/sites/{site-slug}/ - Schema Isolation: Each site has its own database schema
- Environment Types: Production, staging, development, testing
- Custom Configuration: JSON-based site settings
- Nested Access:
/api/organizations/{org-slug}/sites/
Domain
URLs through which sites can be accessed. Enables multi-tenant routing based on domain/subdomain.
- Slug-Based Access:
/api/sites/{site-slug}/domains/{domain-slug}/ - Multi-Domain: Multiple domains per site
- Primary Domain: One canonical domain per site
- Automatic Routing: Request routing based on domain
User
User accounts with authentication and authorization capabilities.
- Slug-Based Access:
/api/users/{user-slug}/ - OAuth Integration: Social authentication support
- Multi-Organization: Users can belong to multiple organizations
- Soft Delete: Audit trail preservation
Group
Collections of users with shared permissions at platform and organization levels.
- Platform-Level: Global groups across the platform
- Organization-Level: Organization-specific groups
- Permission Assignment: Assign permissions to groups
Permission
Fine-grained access control using Django Guardian for object-level permissions.
- Object-Level: Permissions on specific resources
- Role-Based: Predefined roles and custom permissions
- Hierarchical: Permissions cascade through organization hierarchy
Base URL Structure
All Cloud Console endpoints follow slug-based patterns:
# Organizations
/api/organizations/ # List/Create organizations
/api/organizations/{org-slug}/ # Organization details
/api/organizations/{org-slug}/members/ # Organization members
/api/organizations/{org-slug}/members/{user-slug}/ # Specific member
/api/organizations/{org-slug}/invitations/ # Invitations
/api/organizations/{org-slug}/sites/ # Organization sites
# Sites
/api/sites/ # List sites
/api/sites/{site-slug}/ # Site details
/api/sites/{site-slug}/domains/ # Site domains
/api/sites/{site-slug}/domains/{domain-slug}/ # Domain details
/api/sites/config/ # Current site config
# Users
/api/users/ # List/Create users
/api/users/{user-slug}/ # User details
/api/users/{user-slug}/profile/ # User profile
# Groups
/api/groups/ # List/Create groups
/api/groups/{group-id}/ # Group details
# Permissions
/api/permissions/ # List permissions
Quick Start
1. Create an 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",
"slug": "acme-corp",
"name": "Acme Corporation",
"is_active": true,
"created": "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()
2. Create a Site
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"name": "Production Site",
"description": "Main production environment",
"environment": "production"
}'
Response (201 Created):
{
"uuid": "750e8400-e29b-41d4-a716-446655440000",
"slug": "production-site",
"name": "Production Site",
"schema_name": "production_site",
"environment": "production",
"is_active": true
}
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/sites/",
headers=headers,
json={
"name": "Production Site",
"description": "Main production environment",
"environment": "production"
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/sites/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "Production Site",
description: "Main production environment",
environment: "production"
})
})
const data = await response.json()
3. Add a Domain
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/sites/production-site/domains/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"domain": "acme.example.com",
"is_primary": true
}'
Response (201 Created):
{
"uuid": "850e8400-e29b-41d4-a716-446655440000",
"slug": "acme-example-com",
"domain": "acme.example.com",
"is_primary": true,
"is_active": true
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/sites/production-site/domains/",
headers=headers,
json={
"domain": "acme.example.com",
"is_primary": True
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/production-site/domains/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
domain: "acme.example.com",
is_primary: true
})
})
const data = await response.json()
4. Invite a Member
- 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": "user@example.com",
"permissions": ["view_organization", "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": "user@example.com",
"permissions": ["view_organization", "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: "user@example.com",
permissions: ["view_organization", "manage_site"]
})
})
const data = await response.json()
Features
Multi-Tenant Architecture
Complete tenant isolation using PostgreSQL schemas:
- Schema-Based: Each site gets its own database schema
- Data Isolation: No cross-tenant data leakage
- Domain Routing: Automatic tenant detection from domain
- Resource Scoping: All resources scoped to tenants
Authentication & Authorization
Comprehensive auth system with multiple strategies:
- JWT Tokens: Stateless authentication
- Session Auth: Browsable API support
- OAuth/Social: Google, GitHub, etc.
- Object Permissions: Fine-grained access control
Slug-Based Lookups
Human-readable, SEO-friendly URLs:
- Auto-Generated: Slugs created from resource names
- Collision Handling: Automatic numbering (-2, -3, etc.)
- Unique: Enforced uniqueness across resources
- Backward Compatible: UUID lookups still supported
Soft Delete
Audit trail preservation across all resources:
- is_active: Soft delete flag
- is_deleted: Explicit deletion marker
- Cascading: Child resources handled automatically
- Restoration: Easy restoration of deleted resources
Invitation System
Email-based member onboarding:
- Email Invitations: Send invites to new members
- Permission Pre-Assignment: Set permissions before acceptance
- Site Access: Grant specific site access during invite
- Accept/Decline: Members can manage their invitations
API Endpoints by Resource
Organizations
Complete organization management including members, sites, and invitations.
View Organizations Documentation →
Key endpoints:
GET /api/organizations/- List organizationsPOST /api/organizations/- Create organizationGET /api/organizations/{org-slug}/- Get organizationPUT /api/organizations/{org-slug}/- Update organizationDELETE /api/organizations/{org-slug}/- Delete organization
Sites
Manage isolated multi-tenant environments with schema-based isolation.
Key endpoints:
GET /api/sites/- List all sitesGET /api/organizations/{org-slug}/sites/- List organization sitesPOST /api/organizations/{org-slug}/sites/- Create siteGET /api/sites/{site-slug}/- Get site detailsPUT /api/sites/{site-slug}/- Update siteDELETE /api/sites/{site-slug}/- Delete site
Domains
Configure domains for multi-tenant routing to sites.
Key endpoints:
GET /api/sites/{site-slug}/domains/- List site domainsPOST /api/sites/{site-slug}/domains/- Add domainGET /api/sites/{site-slug}/domains/{domain-slug}/- Get domainPATCH /api/sites/{site-slug}/domains/{domain-slug}/- Update domainDELETE /api/sites/{site-slug}/domains/{domain-slug}/- Remove domain
Users
Complete user lifecycle management with authentication.
View User Management Documentation →
Key endpoints:
GET /api/users/- List usersPOST /api/users/- Create userGET /api/users/{user-slug}/- Get user detailsPUT /api/users/{user-slug}/- Update userDELETE /api/users/{user-slug}/- Delete user (soft)
Groups
Organize users into groups with shared permissions.
Key endpoints:
GET /api/groups/- List groupsPOST /api/groups/- Create groupGET /api/groups/{group-id}/- Get group detailsPUT /api/groups/{group-id}/- Update groupDELETE /api/groups/{group-id}/- Delete group
Permissions
Fine-grained access control with object-level permissions.
View Permissions Documentation →
Key endpoints:
GET /api/permissions/- List available permissions- Permission assignment through user/group management
Authentication
All Cloud Console API endpoints require authentication. Taruvi supports multiple authentication methods:
JWT Authentication (Recommended)
- REST API
- Python
- JavaScript
# Get access token
curl -X POST https://your-site.taruvi.cloud/api/auth/jwt/token/ \
-H "Content-Type: application/json" \
-d '{"username": "user@example.com", "password": "your-password"}'
# Response:
# {
# "access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
# "refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
# }
# Use in requests
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/ \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc..."
import requests
# Get access token
auth_response = requests.post(
"https://your-site.taruvi.cloud/api/auth/jwt/token/",
json={"username": "user@example.com", "password": "your-password"}
)
tokens = auth_response.json()
# Use in requests
headers = {"Authorization": f"Bearer {tokens['access']}"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/",
headers=headers
)
data = response.json()
// Get access token
const authResponse = await fetch("https://your-site.taruvi.cloud/api/auth/jwt/token/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "user@example.com", password: "your-password" })
})
const tokens = await authResponse.json()
// Use in requests
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/", {
headers: { "Authorization": `Bearer ${tokens.access}` }
})
const data = await response.json()
Token Refresh
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/auth/jwt/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."}'
import requests
response = requests.post(
"https://your-site.taruvi.cloud/api/auth/jwt/token/refresh/",
json={"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."}
)
new_tokens = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/auth/jwt/token/refresh/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ refresh: "eyJ0eXAiOiJKV1QiLCJhbGc..." })
})
const newTokens = await response.json()
OAuth/Social Authentication
See Social Authentication Documentation for details on:
- Google OAuth
- GitHub OAuth
- Other social providers
Rate Limiting
All endpoints have rate limiting for security:
- Standard: 100 requests per minute
- Authentication: 20 login attempts per hour
- Write Operations: 30 requests per minute
Tenant Isolation
All Cloud Console operations are tenant-scoped:
- Complete data isolation between sites
- Automatic tenant detection from domain
- No cross-tenant data access
- Schema-level separation
Error Handling
Standard HTTP status codes with detailed error messages:
{
"detail": "Not found.",
"code": "not_found",
"status_code": 404
}
Common status codes:
200 OK- Success201 Created- Resource created400 Bad Request- Invalid input401 Unauthorized- Authentication required403 Forbidden- Permission denied404 Not Found- Resource not found429 Too Many Requests- Rate limit exceeded
Pagination
List endpoints support pagination:
- REST API
- Python
- JavaScript
curl -X GET "https://your-site.taruvi.cloud/api/cloud/users/?page=2&page_size=20" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response:
{
"count": 100,
"next": "https://your-site.taruvi.cloud/api/cloud/users/?page=3",
"previous": "https://your-site.taruvi.cloud/api/cloud/users/?page=1",
"results": [...]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/",
headers=headers,
params={"page": 2, "page_size": 20}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/?page=2&page_size=20", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Filtering & Search
Most list endpoints support filtering:
- REST API
- Python
- JavaScript
# Search
curl -X GET "https://your-site.taruvi.cloud/api/cloud/users/?search=john" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Filter by status
curl -X GET "https://your-site.taruvi.cloud/api/cloud/organizations/?is_active=true" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Filter by organization
curl -X GET "https://your-site.taruvi.cloud/api/cloud/users/?organization_slug=acme-corp" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Ordering
curl -X GET "https://your-site.taruvi.cloud/api/cloud/sites/?ordering=-created_at" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
# Search
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/",
headers=headers,
params={"search": "john"}
)
# Filter by status
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/",
headers=headers,
params={"is_active": "true"}
)
# Filter by organization
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/",
headers=headers,
params={"organization_slug": "acme-corp"}
)
# Ordering
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/sites/",
headers=headers,
params={"ordering": "-created_at"}
)
data = response.json()
const headers = { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
// Search
const searchResponse = await fetch("https://your-site.taruvi.cloud/api/cloud/users/?search=john", { headers })
// Filter by status
const activeResponse = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/?is_active=true", { headers })
// Filter by organization
const orgResponse = await fetch("https://your-site.taruvi.cloud/api/cloud/users/?organization_slug=acme-corp", { headers })
// Ordering
const orderedResponse = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/?ordering=-created_at", { headers })
const data = await orderedResponse.json()
Backward Compatibility
UUID Support
While the API now uses slug-based URLs, UUIDs are still supported for backward compatibility:
# Both work:
GET /api/organizations/acme-corp/ # Slug-based (recommended)
GET /api/organizations/{uuid}/ # UUID-based (legacy)
Best Practices
- Use Slugs: Prefer slug-based URLs for better readability and SEO
- Cache Tokens: Store JWT tokens securely and refresh before expiry
- Handle Errors: Implement proper error handling for all requests
- Rate Limiting: Implement exponential backoff for rate limit errors
- Soft Deletes: Deactivate resources instead of hard deleting
- Tenant Context: Always verify tenant context for multi-tenant operations
- Permissions: Follow principle of least privilege
Use Cases
Multi-Company SaaS
Serve multiple companies, each with isolated organizations, sites, and data.
Agency Management
Manage multiple client organizations, each with their own sites and users.
White-Label Platform
Deploy customized instances with custom domains for each customer.
Multi-Environment DevOps
Manage production, staging, and development environments per organization.
Next Steps
- Organizations - Organization management and member control
- Sites - Multi-tenant site deployment and configuration
- Domains - Domain routing and multi-tenant access
- User Management - Complete user lifecycle operations
- Groups - Group-based permission management
- Permissions - Fine-grained access control
- Social Authentication - OAuth and social login integration
Support
For issues or questions:
- Check the detailed documentation for each resource type
- Review error messages and status codes
- Ensure proper authentication and permissions
- Verify tenant context for multi-tenant operations