Custom domains (archived)
Archived: not available today
This page describes the domain flow of the retired sites product (site IDs, IPFS gateways, site verification records). Custom domains for Alternate Clouds services are not available yet and none of these steps work on the current platform. The page is kept for reference and will be replaced when the feature ships. See What changed from af.
Bring your own domain from any registrar (GoDaddy, Namecheap, Cloudflare, etc.) and point it to your Alternate Clouds services.
Overview
By default, sites are accessible via:
- IPFS:
https://gateway.ipfs.io/ipfs/{CID} - Arweave:
https://arweave.net/{TX_ID} - Filecoin:
https://ipfs.io/ipfs/{CID}
Custom domains provide:
- Branded URLs (e.g.,
https://example.com) - Easier to remember and share
- SEO benefits
- Professional appearance
- Automatic SSL/TLS certificates via Let's Encrypt
Adding a Custom Domain
Step 1: Create Domain
Use the GraphQL API or SDK to add your domain:
mutation {
createDomain(input: {
hostname: "example.com"
siteId: "site-123"
verificationMethod: TXT
}) {
id
hostname
txtVerificationToken
verified
}
}Verification Methods:
TXT- TXT record verification (works with root domains and subdomains)CNAME- CNAME record verification (subdomains only)A- A record verification (points to platform IP)
Step 2: Configure DNS Records
Based on your chosen verification method, add the appropriate DNS record at your domain registrar:
DNS configuration methods
Method 1: TXT Record Verification (Recommended)
Add a TXT record to verify domain ownership:
Type: TXT
Name: @ (or your hostname)
Value: af-site-verification=xxxxx (from createDomain response)
TTL: 3600Example:
mutation {
createDomain(input: {
hostname: "example.com"
siteId: "site-123"
verificationMethod: TXT
}) {
id
txtVerificationToken # Use this value
}
}Pros:
- Works with root domains and subdomains
- Non-intrusive (doesn't affect current DNS)
- Easy to verify
Use Case: Best for initial verification before changing DNS routing
Method 2: CNAME Record Verification
Point your subdomain to the platform:
Type: CNAME
Name: www (or subdomain)
Value: cname.alternatefutures.ai
TTL: 3600Example:
mutation {
createDomain(input: {
hostname: "www.example.com"
siteId: "site-123"
verificationMethod: CNAME
}) {
id
expectedCname # Points to platform
}
}Pros:
- Verifies and routes traffic in one step
- Automatic deployment updates
- CDN benefits
Cons:
- Only works with subdomains (not root domains)
Use Case: Best for www.example.com or other subdomains
Method 3: A Record Verification
Point directly to the platform IP:
Type: A
Name: @ (for root domain)
Value: [Platform IP Address]
TTL: 3600Example:
mutation {
createDomain(input: {
hostname: "example.com"
siteId: "site-123"
verificationMethod: A
}) {
id
expectedARecord # Platform IP
}
}Pros:
- Works with root domains
- Verifies and routes in one step
- Fast DNS resolution
Use Case: Best for apex/root domains like example.com
Step 3: Verify Domain
After adding DNS records, verify your domain:
mutation {
verifyDomain(domainId: "domain-123")
}This checks DNS propagation and updates the domain status. You may need to wait a few minutes for DNS changes to propagate globally.
Check verification status:
query {
domain(id: "domain-123") {
id
hostname
verified
txtVerificationStatus
dnsCheckAttempts
lastDnsCheck
}
}SSL/TLS Certificates
Once your domain is verified, provision an SSL certificate:
mutation {
provisionSsl(
domainId: "domain-123"
email: "admin@example.com"
) {
id
sslStatus
sslIssuedAt
sslExpiresAt
}
}SSL Features:
- Automatic Let's Encrypt certificate provisioning
- Auto-renewal 30 days before expiry
- HTTP-01 and DNS-01 ACME challenges supported
- Free SSL for all domains
Certificate Process:
- Domain must be verified first
- Request SSL certificate via
provisionSslmutation - Wait 5-10 minutes for Let's Encrypt validation
- Certificate automatically installed and renewed
Domain status
Verification Status:
PENDING- DNS not yet propagatedVERIFIED- Domain ownership confirmedFAILED- DNS misconfigured or verification failed
SSL Status:
NONE- No certificate requestedPENDING- Certificate being provisionedACTIVE- SSL certificate active and workingFAILED- Certificate provisioning failed
Check status:
query {
domain(id: "domain-123") {
verified
txtVerificationStatus
sslStatus
sslExpiresAt
}
}Managing multiple domains
List all domains
Get all domains for a site:
query {
site(id: "site-123") {
id
domains {
id
hostname
verified
sslStatus
createdAt
}
}
}Set the primary domain
Set a verified domain as the primary domain for your site:
mutation {
setPrimaryDomain(
siteId: "site-123"
domainId: "domain-123"
) {
id
primaryDomain {
hostname
}
}
}Requirements:
- Domain must be verified
- Only verified domains can be primary
Remove a domain
Remove a custom domain:
mutation {
removeDomain(domainId: "domain-123")
}Note: Cannot remove a domain that is set as primary. Set a different primary domain first.
Common multi-domain setup
Add multiple domains for different purposes:
- Primary domain:
example.com - WWW subdomain:
www.example.com - Regional domains:
example.co.uk,example.ca - Staging domains:
staging.example.com
Each domain can have its own SSL certificate and verification method.
Troubleshooting
Verification failing
1. Check DNS propagation:
dig example.com TXT
dig www.example.com CNAME
dig example.com ADNS changes can take 5 minutes to 48 hours to propagate globally.
2. Verify correct DNS values:
For TXT verification:
dig example.com TXT | grep "af-site-verification"For CNAME verification:
dig www.example.com CNAME
# Should show: cname.alternatefutures.aiFor A record verification:
dig example.com A
# Should show platform IP3. Common verification issues:
- DNS not propagated yet (wait 5-60 minutes)
- Wrong record type (TXT vs CNAME vs A)
- Incorrect hostname (@ vs www vs subdomain)
- Typo in verification token
- TTL too high (recommended: 3600 seconds)
4. Check verification attempts:
query {
domain(id: "domain-123") {
dnsCheckAttempts
lastDnsCheck
txtVerificationStatus
}
}If attempts > 10 and still failing, double-check DNS configuration.
SSL certificate issues
Check certificate status:
query {
domain(id: "domain-123") {
sslStatus
sslIssuedAt
sslExpiresAt
}
}Common issues:
-
Domain not verified
- Error: "Domain must be verified before provisioning SSL"
- Solution: Complete DNS verification first
-
Certificate provisioning stuck on PENDING
- DNS not fully propagated
- CAA records blocking Let's Encrypt
- Port 80/443 not accessible for HTTP-01 challenge
- Wait 10-15 minutes and check again
-
Certificate expired
- Certificates auto-renew 30 days before expiry
- Check:
sslExpiresAtfield - Re-provision if needed: Run
provisionSslmutation again
Test SSL certificate:
curl -vI https://example.com
openssl s_client -connect example.com:443 -servername example.comDNS provider-specific issues
Cloudflare:
- Disable "orange cloud" proxy for verification
- Use "DNS only" (grey cloud) mode initially
- Re-enable proxy after verification completes
GoDaddy:
- DNS propagation can be slow (24-48 hours)
- Use shorter TTL values (600-3600 seconds)
Namecheap:
- Use
@for root domain TXT records - Use
wwwfor CNAME records (notwww.example.com)
Google Domains / Cloud DNS:
- Include trailing dot in CNAME if required
- Example:
cname.alternatefutures.ai.
Supported DNS Providers
Tested and working with:
- Cloudflare - Fast propagation (5-15 min), excellent DNS management
- Namecheap - Good propagation (30-60 min)
- GoDaddy - Slower propagation (2-24 hours)
- Google Domains - Fast and reliable
- AWS Route53 - Enterprise-grade, fast propagation
- DigitalOcean DNS - Fast and simple
- Vercel DNS - Fast propagation
All major DNS providers support TXT, CNAME, and A records needed for domain verification.
Web3 Domains
ArNS (Arweave Name System)
Register permanent domains on Arweave:
mutation {
registerArnsName(
siteId: "site-123"
arnsName: "my-site"
) {
name
transactionId
contentId
}
}Features:
- Permanent, immutable domains
- Stored on Arweave blockchain
- Access via:
my-site.arweave.net
ENS (Ethereum Name System)
Link ENS domains to your content:
mutation {
linkEnsDomain(
siteId: "site-123"
ensName: "mysite.eth"
) {
ensName
contentHash
resolverAddress
}
}Features:
- Ethereum-based domain names
- Decentralized DNS alternative
- Access via ENS-compatible browsers
IPNS (IPFS Name System)
Create mutable IPNS pointers:
mutation {
createIpnsName(
siteId: "site-123"
ipnsName: "my-ipns-site"
) {
ipnsName
ipnsHash
currentCid
}
}Features:
- Mutable pointers to IPFS content
- Update content without changing address
- Access via:
/ipns/{hash}
Complete example workflow
Here's a complete example of adding a custom domain with SSL:
# Step 1: Create domain with TXT verification
mutation CreateDomain {
createDomain(input: {
hostname: "example.com"
siteId: "site-abc123"
verificationMethod: TXT
}) {
id
hostname
txtVerificationToken
}
}
# Response:
# {
# "id": "domain-xyz789",
# "hostname": "example.com",
# "txtVerificationToken": "af-site-verification=abc123def456"
# }
# Step 2: Add DNS TXT record at your registrar
# Type: TXT
# Name: @
# Value: af-site-verification=abc123def456
# TTL: 3600
# Step 3: Wait 5-60 minutes for DNS propagation
# Test with: dig example.com TXT
# Step 4: Verify domain
mutation VerifyDomain {
verifyDomain(domainId: "domain-xyz789")
}
# Step 5: Check verification status
query CheckDomain {
domain(id: "domain-xyz789") {
verified
txtVerificationStatus
}
}
# Step 6: Provision SSL certificate
mutation ProvisionSSL {
provisionSsl(
domainId: "domain-xyz789"
email: "admin@example.com"
) {
sslStatus
sslIssuedAt
sslExpiresAt
}
}
# Step 7: Wait 5-10 minutes for Let's Encrypt
# Your site is now live at https://example.com!
# Step 8: Set as primary domain (optional)
mutation SetPrimary {
setPrimaryDomain(
siteId: "site-abc123"
domainId: "domain-xyz789"
) {
id
primaryDomain {
hostname
}
}
}API reference
Mutations
createDomain - Add a custom domain
- Input:
CreateDomainInput - Returns:
Domain
verifyDomain - Verify domain ownership
- Input:
domainId: ID! - Returns:
Boolean
provisionSsl - Request SSL certificate
- Input:
domainId: ID!,email: String! - Returns:
Domain
setPrimaryDomain - Set primary domain for site
- Input:
siteId: ID!,domainId: ID! - Returns:
Site
removeDomain - Remove custom domain
- Input:
domainId: ID! - Returns:
Boolean
Queries
domain - Get domain by ID
- Input:
id: ID! - Returns:
Domain
domains - List all domains for a site
- Input:
siteId: ID! - Returns:
[Domain!]!
Next steps
- Projects - Organize services and members
- Troubleshooting - DNS and certificate issues
- Quick start - Deploy a service to point a domain at