Documentation

Set Up a Custom Domain

Assign a custom domain to your app site, configure DNS, verify SSL, and re-deploy.

Connect your own domain (e.g., privacy.myapp.com) to your OrbitKit app site.

Prerequisites: A deployed app site and access to your domain registrar’s DNS settings. See the Create & Deploy guide if you haven’t deployed yet.

Steps

  1. Assign the domain

    curl -X PUT https://api.orbitkit.io/api/apps/$APP_ID/site/domain \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"domain": "privacy.myapp.com"}'
    
    var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/site/domain")!)
    request.httpMethod = "PUT"
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try JSONEncoder().encode(["domain": "privacy.myapp.com"])
    
    let (data, _) = try await URLSession.shared.data(for: request)
    let dns = try JSONDecoder().decode(DomainResponse.self, from: data)
    
    const res = await fetch(
      `https://api.orbitkit.io/api/apps/${appId}/site/domain`,
      {
        method: "PUT",
        headers: {
          Authorization: `Bearer ${token}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ domain: "privacy.myapp.com" }),
      }
    );
    const dns = await res.json();
    

    The response includes DNS instructions (an A record and a CNAME record).

  2. Configure DNS at your domain registrar:
    • Add the A record pointing to OrbitKit’s IP
    • Add the CNAME record for the ACME challenge
  3. Check domain status (poll until status is "active"):

    curl https://api.orbitkit.io/api/apps/$APP_ID/site/domain/status \
      -H "Authorization: Bearer $TOKEN"
    
    let url = URL(string: "https://api.orbitkit.io/api/apps/\(appId)/site/domain/status")!
    var request = URLRequest(url: url)
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    
    let (data, _) = try await URLSession.shared.data(for: request)
    let status = try JSONDecoder().decode(DomainStatus.self, from: data)
    
    const res = await fetch(
      `https://api.orbitkit.io/api/apps/${appId}/site/domain/status`,
      { headers: { Authorization: `Bearer ${token}` } }
    );
    const { status } = await res.json();
    

    DNS propagation typically takes 5–30 minutes. SSL provisioning follows automatically.

  4. Re-deploy to serve pages on the custom domain:

    curl -X POST https://api.orbitkit.io/api/apps/$APP_ID/deploy \
      -H "Authorization: Bearer $TOKEN"
    
    var request = URLRequest(url: URL(string: "https://api.orbitkit.io/api/apps/\(appId)/deploy")!)
    request.httpMethod = "POST"
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    
    let (data, _) = try await URLSession.shared.data(for: request)
    
    const res = await fetch(
      `https://api.orbitkit.io/api/apps/${appId}/deploy`,
      {
        method: "POST",
        headers: { Authorization: `Bearer ${token}` },
      }
    );
    

Tips

  • Use exponential backoff when polling domain status (start at 30 seconds, double each time, cap at 5 minutes)
  • See the Custom Domains endpoint reference for full details
  • For dashboard-based setup, see the Custom Domains docs