Build and Ship

Custom Domains

Expose a running service, attach your own domain, and share it over HTTPS.

Each coding agent runs in its own sandboxed VM. By default, services inside the VM are not reachable from the internet. Exposed Ports opens a port, proxies it through the live worker connection, and gives you a public HTTPS URL — or lets you connect your own domain.

Exposing a port#

  1. Go to your agent's Settings tab.
  2. Under Exposed Ports, enter the port your service listens on (e.g. 3000).
  3. Click Expose Port.
  4. You get a public URL immediately. On production this is a subdomain like https://myagent-abc12345-3000.ports.chat.dev; some environments (e.g. staging) use a path-based URL like https://<server>/p/<agentId>/<port> instead — always use the exact URL shown in Settings.

TLS certificates are provisioned automatically.

The port proxy uses the live worker websocket, so exposing a port does not by itself require restarting a running machine. The service inside the VM still has to be listening on that port.

What the proxy supports#

  • Plain HTTP and HTTPS — all methods, request bodies, and response streaming (SSE and chunked responses are forwarded live).
  • Redirects — passed through to the browser, so OAuth callbacks and login flows work.
  • Not supported: WebSockets. Upgrade requests get a 501 — the public URL terminates at an HTTP proxy that can't carry a WebSocket connection. If your app needs realtime updates behind an exposed port, use SSE or polling instead.

Connecting a custom domain#

Point your own domain at any exposed port. This works with any registrar (Porkbun, Namecheap, Cloudflare, GoDaddy, etc.).

1. Expose the port#

Make sure the port is exposed first (see above). You need the auto-generated URL as your CNAME target.

2. Add the domain in chat.dev#

  1. In Settings, scroll to Custom Domains.
  2. Enter your domain (e.g. app.example.com) and select which exposed port it should route to.
  3. Click Add Domain.
  4. You'll see a CNAME target to configure in your DNS.

3. Add a CNAME record at your registrar#

In your registrar's DNS settings, add a CNAME record:

TypeNameTarget
CNAMEappmyagent-abc12345-3000.ports.chat.dev
  • For app.example.com, the Name is app.
  • For root domains (example.com), you need a registrar that supports CNAME flattening (e.g. Cloudflare).
  • TTL: automatic or 300 seconds.

4. Verify and get TLS#

  1. Back in chat.dev, click Verify next to your domain.
  2. chat.dev checks that your CNAME resolves correctly.
  3. A TLS certificate is automatically provisioned once verified.
  4. Your domain is live with HTTPS within a few minutes.

Troubleshooting#

  • "No CNAME record found" — DNS propagation can take a few minutes. Wait and try again.
  • CNAME target mismatch — Make sure the value exactly matches the target shown in chat.dev.
  • Port URL opens but the app does not load — confirm the process is listening on 0.0.0.0:<port> or 127.0.0.1:<port> inside the agent VM and that the exposed port number matches.
  • Root domain — CNAME records can't be set on bare root domains. Use a subdomain or a registrar with CNAME flattening.

Multiple ports#

You can expose multiple ports on the same agent. Each gets its own URL and can have its own custom domain — useful for running a frontend on port 3000 and an API on port 8080, for example.

Removing ports and domains#

  • To remove a custom domain, click the delete button next to it in Settings. The TLS certificate is cleaned up automatically.
  • To remove an exposed port, click the delete button. This also removes any custom domains attached to that port.