packages/cloud-frontend/content/app-domains.mdx
import { Callout, Steps, Tabs, Cards } from "@/docs/components";
Configure custom domains for your multi-tenant applications with automatic SSL and DNS management.
<div className="status-badge status-stable">Stable</div>Domain management in elizaOS Cloud supports:
*.apps.elizacloud.ai subdomains for every appmyapp.com or app.example.comNavigate to Dashboard → Apps and select an app to manage its domains.
# Add a custom domain to your app
curl -X POST "https://elizacloud.ai/api/v1/apps/{appId}/domains" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "myapp.example.com"
}'
When you deploy an app, it automatically receives a subdomain like myapp.apps.elizacloud.ai.
Add your own domain and configure DNS records.
Vercel automatically provisions SSL certificates for all domains.
Requests are routed to your app based on the incoming domain.
</Steps>Every deployed app automatically gets a subdomain under apps.elizacloud.ai:
https://myapp.apps.elizacloud.ai
This works immediately with no DNS configuration required.
| Rule | Example | Valid |
|---|---|---|
| Min 3 characters | ab | ❌ |
| Max 63 characters | my-long-subdomain... | ✅ |
| Alphanumeric + hyphens | my-app-v2 | ✅ |
| No leading/trailing hyphens | -myapp- | ❌ |
| Lowercase only | MyApp → myapp | Auto-converted |
The following subdomains are reserved and cannot be used:
www, api, admin, dashboard, app, appsauth, login, signup, register, accountcdn, static, assets, media, webhookstaging, dev, test, demo, preview, betaCustom domains let you use your own branded URLs like myapp.com or app.company.com.
curl -X POST "https://elizacloud.ai/api/v1/apps/{appId}/domains" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "myapp.example.com"
}'
{
"success": true,
"domain": "myapp.example.com",
"verified": false,
"verificationRecords": [
{
"type": "TXT",
"name": "_vercel.myapp.example.com",
"value": "vc-domain-verify=abc123..."
}
],
"dnsInstructions": [
{
"type": "CNAME",
"name": "myapp",
"value": "cname.vercel-dns.com"
}
],
"isApexDomain": false
}
For subdomains like app.example.com:
| Type | Name | Value |
|---|---|---|
| CNAME | app | cname.vercel-dns.com |
For apex domains like example.com:
| Type | Name | Value |
|---|---|---|
| A | @ | 76.76.21.21 |
If your domain is already registered elsewhere on Vercel, you'll need to add a TXT record to verify ownership.
curl -X POST "https://elizacloud.ai/api/v1/apps/{appId}/domains/verify" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "myapp.example.com"
}'
{
"success": true,
"verified": true,
"status": {
"domain": "myapp.example.com",
"status": "valid",
"configured": true,
"verified": true,
"sslStatus": "provisioning",
"configuredBy": "CNAME",
"isApexDomain": false
}
}
Monitor your domain's DNS and SSL status:
curl -X POST "https://elizacloud.ai/api/v1/apps/{appId}/domains/status" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "myapp.example.com"
}'
{
"success": true,
"domain": "myapp.example.com",
"status": "valid",
"configured": true,
"verified": true,
"sslStatus": "active",
"sslExpiresAt": "2025-04-15T00:00:00Z",
"configuredBy": "CNAME",
"records": [],
"isApexDomain": false,
"dnsInstructions": [
{
"type": "CNAME",
"name": "myapp",
"value": "cname.vercel-dns.com"
}
]
}
| Status | Description |
|---|---|
pending | DNS records not yet detected |
valid | Domain properly configured |
invalid | DNS misconfigured, check records |
unknown | Domain not found in project |
| SSL Status | Description |
|---|---|
pending | Awaiting DNS verification |
provisioning | Certificate being issued |
active | Certificate active and valid |
error | Certificate issue (check configuration) |
Refresh all domain statuses for an app:
curl -X POST "https://elizacloud.ai/api/v1/apps/{appId}/domains/sync" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"success": true,
"domains": [
{
"id": "dom_abc123",
"subdomain": "myapp",
"subdomainUrl": "https://myapp.apps.elizacloud.ai",
"customDomain": "myapp.example.com",
"customDomainUrl": "https://myapp.example.com",
"customDomainVerified": true,
"sslStatus": "active",
"isPrimary": true
}
],
"syncedAt": "2025-01-05T12:00:00Z"
}
Remove a custom domain from your app:
curl -X DELETE "https://elizacloud.ai/api/v1/apps/{appId}/domains" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "myapp.example.com"
}'
For the best user experience, configure both apex and www versions:
example.com and www.example.com to your app| Domain | Type | Value |
|---|---|---|
example.com | A | 76.76.21.21 |
www.example.com | CNAME | cname.vercel-dns.com |
If the same app is accessible via both subdomain and custom domain:
<Tabs items={["Canonical Tags", "Redirects"]}>
<Tabs.Tab>
Add canonical tags to your HTML <head>:
<link rel="canonical" href="https://myapp.example.com/page" />
</Tabs.Tab>
<Tabs.Tab> Configure redirects from subdomain to custom domain:
{
"redirects": [
{
"source": "/:path*",
"destination": "https://myapp.example.com/:path*",
"permanent": true
}
]
}
</Tabs.Tab> </Tabs>
Problem: Domain not working after adding DNS records.
Solution:
Problem: TXT record verification not working.
Solution:
_vercel prefixProblem: SSL status stuck on "pending" or "provisioning".
Solution:
Problem: Error saying domain is already connected to another project.
Solution:
Problem: Preview URLs fail due to length.
Solution:
elizaOS Cloud blocks domains with:
xn-- prefixes)This prevents phishing attacks using visually similar domain names.
All domains are validated for:
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/apps/{id}/domains | List all domains |
| POST | /api/v1/apps/{id}/domains | Add custom domain |
| DELETE | /api/v1/apps/{id}/domains | Remove custom domain |
| POST | /api/v1/apps/{id}/domains/verify | Verify domain ownership |
| POST | /api/v1/apps/{id}/domains/status | Check domain status |
| POST | /api/v1/apps/{id}/domains/sync | Sync all domain statuses |
*.apps.elizacloud.ai before adding custom domainssslExpiresAt in status responses (auto-renewed)