Skip to main content
Every Frame gets a Nubo-assigned domain out of the box. When you’re ready to go live you can attach a custom domain (anything like shop.mystore.com, api.mysite.io, or even a root domain) and Nubo will serve the Frame there with HTTPS. The exact DNS you’ll set up depends on whether the Frame runs on managed infrastructure (our cloud) or a self-hosted agent (your own server). The API is the same either way.

Add a domain from the dashboard

Open the Frame’s Settings tab and find the Custom domains section. Hit Add domain and the setup wizard walks you through four steps:
  1. Enter your hostname.
  2. Update DNS with the record we give you.
  3. Issuing TLS: we wait for your certificate to be issued and show progress while it happens.
  4. Live: the domain is serving traffic.
Most domains go from added to live in under a minute once DNS has propagated. HTTPS is on by default.

Add a domain via the API

curl -X POST https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id>/domains \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{"hostname": "shop.mystore.com"}'
The response tells you exactly which DNS records to create. The shape differs by infrastructure.
Using a root/apex domain (like mystore.com rather than shop.mystore.com)? A plain CNAME isn’t valid at a zone apex, so it will be rejected at most registrars. Use an ALIAS or ANAME record, or a provider that supports CNAME flattening, pointing at the same target Nubo gives you.

Managed Frames

You’ll create a single CNAME record pointing at the value Nubo gives you back:
{
  "hostname": "shop.mystore.com",
  "dns": {
    "record_type": "CNAME",
    "record_name": "shop.mystore.com",
    "record_value": "<value returned by the API>"
  }
}
Add it to your registrar. Then tell Nubo to verify:
curl -X POST https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id>/domains/shop.mystore.com/verify \
  -H "Authorization: Bearer <your-token>"
Once DNS resolves to the right target, Nubo issues a free certificate and starts serving traffic at your hostname. You can call /verify again any time to re-poll.

Self-hosted agent Frames

Agent Frames provision TLS automatically - no verification step:
{
  "hostname": "shop.mystore.com",
  "dns": {
    "record_type": "CNAME",
    "record_name": "shop.mystore.com",
    "record_value": "abc123.frames.example.com"
  }
}
Add the single CNAME, pointing at either the Frame’s system subdomain or the agent’s base domain - any name that resolves to the agent’s IP works. Once the CNAME is in place, Caddy provisions the certificate automatically the next time it reloads its config (shortly after the domain is attached), and the Frame is live.
For agent Frames, ACME needs at least one of port 80 (HTTP-01) or port 443 (TLS-ALPN-01) reachable from the public internet for automatic TLS issuance to work. Caddy tries both, and if both are firewalled, TLS provisioning will fail.

Verify it’s working

Once DNS has propagated (usually seconds to a few minutes):
curl -vI https://shop.mystore.com
You should get a 200 back with a valid certificate. dig shop.mystore.com should show your CNAME resolving to the right target.

Remove a domain

curl -X DELETE https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id>/domains/shop.mystore.com \
  -H "Authorization: Bearer <your-token>"
This detaches the hostname from the Frame and stops serving traffic there. Remove the CNAME from your registrar once you’re done.

List attached domains

curl https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id>/domains \
  -H "Authorization: Bearer <your-token>"
Returns the Frame’s system domain(s) plus every custom domain attached, with their current status (pending, provisioning, active, or error). A domain shows provisioning while its certificate is being issued.

Troubleshooting

Status stuck on pending

  • Managed: your CNAME isn’t resolving to the value Nubo handed you yet. Re-check your DNS (dig shop.mystore.com) and call /verify again.
  • Agent: the agent was offline when the domain was added. Attach tasks aren’t replayed on reconnect, so once the agent is back online, re-add the domain: DELETE it, then POST it again.

TLS certificate error

  • DNS propagated? dig shop.mystore.com should return the expected target.
  • Port 80 or 443 reachable? (Agent Frames only.) ACME needs at least one of port 80 (HTTP-01) or port 443 (TLS-ALPN-01) open to the public internet for automatic TLS issuance. Caddy tries both, and if both are firewalled, provisioning fails.
  • Rate-limited? Certificate authorities cap issuance per hostname per week. If you’ve retried a lot, wait an hour.
For agent Frames, check the agent logs for TLS issuance details: journalctl -fu nubo-agent (Linux) or tail -f ~/Library/Logs/nubo-agent/stderr.log (macOS).

Hostname already registered

Each hostname belongs to one Frame at a time across all of Nubo. If you try to attach one that’s already in use, the API returns a 400. Remove it from the other Frame first, or pick a different hostname.