Domains
Domains are the URLs through which sites can be accessed in Taruvi Cloud. Each site can have multiple domains, but only one can be designated as the primary domain.
All domain endpoints now use slug-based URLs for sites and domains (e.g., /api/cloud/sites/production-site/domains/primary-domain/) instead of UUID-based URLs. Slugs are human-readable identifiers automatically generated from the site/domain names. UUIDs are still supported for backward compatibility.
Overview
Domains link URLs to sites (tenants), enabling multi-tenant routing. When a request comes to a specific domain, Taruvi automatically routes it to the correct site's database schema.
Key capabilities:
- Multiple Domains per Site: A site can be accessed through multiple domains
- Primary Domain: One domain per site serves as the primary/default
- Automatic Routing: Requests are automatically routed to the correct tenant
- Subdomain Support: Support for both subdomains and custom domains
Key Features
Multi-Domain Support
Each site can have multiple domains pointing to it:
- Primary domain for canonical URL
- Additional domains for aliases or regional access
- Development and production domain separation
Primary Domain Enforcement
Database constraints ensure:
- Only one domain can be marked as primary per site
- Primary domain designation is handled safely with transaction locks (
select_for_update()) - Prevents race conditions in concurrent requests
- Setting
is_primary=trueautomatically sets all other domains for the site tois_primary=false
Tenant Routing
Domains enable automatic tenant detection:
- Incoming request domain identifies the tenant
- Correct database schema is automatically selected
- Complete data isolation between tenants
Using Domains
Creating a Domain
Add a new domain to a site:
POST /api/cloud/sites/{site_slug}/domains/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"domain": "acme.example.com",
"is_primary": true
}
Example:
POST /api/cloud/sites/production-site/domains/
{
"domain": "acme.example.com",
"is_primary": true
}
Response:
{
"uuid": "850e8400-e29b-41d4-a716-446655440000",
"slug": "acme-example-com",
"domain": "acme.example.com",
"is_primary": true,
"is_active": true,
"tenant": "750e8400-e29b-41d4-a716-446655440000",
"created_at": "2024-01-15T10:30:00Z",
"modified_at": "2024-01-15T10:30:00Z"
}
Note: When you set is_primary: true, any existing primary domain for that site is automatically changed to non-primary.
Listing Domains
Get all domains for a site:
GET /api/cloud/sites/{site_slug}/domains/
Authorization: Bearer YOUR_ACCESS_TOKEN
Query Parameters:
is_active: Filter by active statustrueor1: Only active domains (default)falseor0: Only inactive domainsallor*: All domains regardless of status
is_primary: Filter by primary status (trueorfalse)search: Search by domain nameordering: Sort results (default:-is_primary,domain)
Example:
GET /api/cloud/sites/production-site/domains/
Response:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"uuid": "850e8400-e29b-41d4-a716-446655440000",
"slug": "acme-example-com",
"domain": "acme.example.com",
"is_primary": true,
"is_active": true
},
{
"uuid": "850e8400-e29b-41d4-a716-446655440001",
"slug": "acme-prod-example-com",
"domain": "acme-prod.example.com",
"is_primary": false,
"is_active": true
},
{
"uuid": "850e8400-e29b-41d4-a716-446655440002",
"slug": "www-acme-custom-com",
"domain": "www.acme-custom.com",
"is_primary": false,
"is_active": true
}
]
}
Retrieving Domain Details
Get details of a specific domain:
GET /api/cloud/sites/{site_slug}/domains/{domain_slug}/
Authorization: Bearer YOUR_ACCESS_TOKEN
Example:
GET /api/cloud/sites/production-site/domains/acme-example-com/
Updating a Domain
Update domain settings:
PUT /api/cloud/sites/{site_slug}/domains/{domain_slug}/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"domain": "new-acme.example.com",
"is_primary": false,
"is_active": true
}
Example:
PUT /api/cloud/sites/production-site/domains/acme-example-com/
{
"domain": "new-acme.example.com",
"is_active": true
}
Setting Primary Domain
Change which domain is primary:
PATCH /api/cloud/sites/{site_slug}/domains/{domain_slug}/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"is_primary": true
}
Example:
PATCH /api/cloud/sites/production-site/domains/acme-prod-example-com/
{
"is_primary": true
}
This automatically:
- Sets the specified domain as primary
- Changes the previous primary domain to non-primary
- Uses transaction locking to prevent race conditions
Deleting a Domain
Remove a domain from a site:
DELETE /api/cloud/sites/{site_slug}/domains/{domain_slug}/
Authorization: Bearer YOUR_ACCESS_TOKEN
Example:
DELETE /api/cloud/sites/production-site/domains/acme-example-com/
- You cannot delete the last primary domain of a site
- At least one domain must exist for the site to be accessible
- Attempting to delete the last primary domain returns a 400 error
Domain Types
Subdomains
Subdomains of your main platform domain:
customer1.taruvi.com
customer2.taruvi.com
staging.customer1.taruvi.com
Custom Domains
Customer-owned domains:
app.acmecorp.com
portal.example.com
www.customdomain.com
Development vs Production Domains
Development Domains
For local development, use .nip.io domains:
# Development domain pattern
http://tenant-name.127.0.0.1.nip.io:8000
# Example
http://acme.127.0.0.1.nip.io:8000
The .nip.io service automatically resolves to 127.0.0.1, enabling subdomain-based multi-tenancy in local development.
Production Domains
In production, configure proper DNS records:
# Subdomain approach
acme.yourdomain.com
# Custom domain approach
app.acmecorp.com
Primary Domain Management
Why Primary Domains Matter
The primary domain serves as:
- The canonical URL for the site
- The default domain for generated links
- The reference for SEO and indexing
Automatic Primary Domain Handling
When setting a domain as primary:
PATCH /api/cloud/sites/{site_slug}/domains/{domain_slug}/
{
"is_primary": true
}
Example:
PATCH /api/cloud/sites/production-site/domains/acme-example-com/
{
"is_primary": true
}
Taruvi automatically:
- Acquires a database lock on the site
- Sets all other domains to
is_primary: false - Sets the specified domain to
is_primary: true - Releases the lock
This ensures only one primary domain exists even under concurrent requests.
DNS Configuration
Subdomain Setup
For subdomains, configure a wildcard DNS record:
Type: A or CNAME
Name: *.yourdomain.com
Value: Your server IP or hostname
Custom Domain Setup
For custom domains, customers need to create a CNAME record:
Type: CNAME
Name: app (or subdomain)
Value: your-platform.com
Permissions
Domain management requires site-level permissions:
manage_site: Can add, edit, and delete domainsview_site: Can view domain configuration
Best Practices
- Always Set a Primary: Ensure each site has one primary domain
- Use Descriptive Names: Choose domain names that clearly indicate the site purpose
- Development Isolation: Use
.nip.iofor local development to match production behavior - DNS Propagation: Allow 24-48 hours for DNS changes to fully propagate
- SSL Certificates: Configure SSL/TLS certificates for all production domains
- Monitoring: Monitor domain resolution and routing for all sites
Common Patterns
Multiple Environment Domains
[
{
"domain": "acme-prod.example.com",
"is_primary": true,
"is_active": true
},
{
"domain": "acme-staging.example.com",
"is_primary": false,
"is_active": true
},
{
"domain": "acme-dev.example.com",
"is_primary": false,
"is_active": true
}
]
White-Label with Custom Domains
[
{
"domain": "customer.yourplatform.com",
"is_primary": true,
"is_active": true
},
{
"domain": "app.customercorp.com",
"is_primary": false,
"is_active": true
}
]
Regional Domains
[
{
"domain": "acme-us.example.com",
"is_primary": true,
"is_active": true
},
{
"domain": "acme-eu.example.com",
"is_primary": false,
"is_active": true
},
{
"domain": "acme-asia.example.com",
"is_primary": false,
"is_active": true
}
]
Troubleshooting
Domain Not Routing to Site
- Verify domain exists in database
- Check
is_activeis set totrue - Confirm DNS records are correctly configured
- Check tenant middleware is enabled
- Verify site schema exists
Primary Domain Conflicts
If you encounter issues with primary domains:
- Check database constraint
one_primary_domain_per_site - Query domains:
GET /api/cloud/sites/{site_slug}/domains/ - Manually set correct primary domain
Local Development Not Working
For local development issues:
- Ensure using
.nip.iodomain format - Verify port is included:
tenant.127.0.0.1.nip.io:8000 - Check domain exists for the tenant
- Confirm development settings allow local domains
Related Features
- Sites - Manage sites that domains point to
- Organizations - Organization-level site management