> ## Documentation Index
> Fetch the complete documentation index at: https://docs.edgespark.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Bind a custom domain to your EdgeSpark project

> Add your own hostname with edgespark domain add, publish the printed DNS records, and run edgespark domain verify to wait for activation and TLS.

Every EdgeSpark project ships behind a platform-managed default URL like `your-project.edgespark.app`. To serve your own purchased hostname instead, use the `edgespark domain` family of CLI commands. The CLI prints exactly the DNS records you need; the platform handles ownership verification, EdgeSpark routing, and TLS certificate issuance.

You stay in your project directory the whole time. Each command resolves the project from `edgespark.toml` and your authenticated CLI session.

## Add a domain

```bash theme={null}
edgespark domain add app.example.com
```

The CLI registers the hostname against your project and returns the DNS records to publish. The actual record names and values are computed per project — copy them verbatim from the CLI output. A subdomain looks like:

```text theme={null}
Domain added

Hostname: app.example.com
Status:   pending

DNS records
  CNAME  app.example.com -> custom.edgespark.app
        Purpose: routing
  TXT    _edgespark-verify-<scoped>.app.example.com -> edgespark-domain-verification=<token>
        Purpose: ownership

User action required
  1. Add every DNS record above at the domain's DNS provider.
     For apex/root domains, use @ if your DNS provider asks for a host/name.
  2. Wait for DNS propagation; EdgeSpark certificate issuance is automatic.
  3. Run `edgespark domain verify app.example.com` to wait for activation.
```

Publish every record in the list — the `CNAME` makes traffic flow, and the `TXT` is what EdgeSpark uses to prove the domain belongs to you. The `<scoped>` segment of the TXT name is derived from your project ID, so two projects can never claim the same hostname with conflicting tokens.

If your DNS provider supports [domain-connect](https://www.domainconnect.org/), `add` may also print a `Setup URL` you can open to add the records with one click instead of copy-pasting.

<Note>
  EdgeSpark uses a `TXT` ownership challenge — there is no nameserver delegation. Your existing DNS provider stays in charge.
</Note>

## Verify activation

After publishing the DNS records, wait for the domain to flip active:

```bash theme={null}
edgespark domain verify app.example.com
```

The command polls every 15 seconds until the domain is active or the timeout is reached. Default timeout is 15 minutes; raise it for slow DNS or busy certificate authorities:

```bash theme={null}
edgespark domain verify app.example.com --timeout 30m
```

`--timeout` accepts `ms`, `s`, `m`, `h` units (e.g. `90s`, `5m`, `1h`).

When activation succeeds:

```text theme={null}
Domain verified and active

Hostname: app.example.com
Status:   active
URL:      https://app.example.com
```

If the timeout elapses before activation, the CLI prints the current status, repeats any DNS records still missing, and exits 0 so you can re-run `verify` later. The domain is not lost — it stays registered on the project.

## Inspect a domain

`status` is a one-shot read of where a domain stands. It does not poll:

```bash theme={null}
edgespark domain status app.example.com
```

Output includes the activation `Status`, the platform's view of routing health (`EdgeSpark routing`), the TLS certificate state (`SSL`), any warnings, and the DNS records still pending if setup is incomplete.

```text theme={null}
Hostname:          app.example.com
Status:            active
EdgeSpark routing: active
SSL:               active
URL:               https://app.example.com
```

`Status` is the high-level activation flag. `EdgeSpark routing` and `SSL` are independent, finer-grained strings sourced from the platform's CDN integration — when a domain is stuck in `pending`, look at those two fields to tell DNS-side problems apart from TLS-issuance problems.

Use `status` for spot checks; use `verify` when you want the CLI to wait.

## List domains

```bash theme={null}
edgespark domain list
```

Prints a table of every custom domain on the current project with its status and live URL. Use this from CI or scripts to confirm what is wired up.

## Remove a domain

```bash theme={null}
edgespark domain remove app.example.com
```

Detaches the hostname from the project. The CLI returns the post-removal status; depending on your DNS provider, you may also want to delete the `CNAME` and `TXT` records at the source.

## Domain status values

The high-level `Status` field can take five values:

| Status     | Meaning                                                     | What to do                                                                                                                                                                              |
| ---------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pending`  | Registered; ownership / routing / TLS not yet all confirmed | Confirm the records are published, then `edgespark domain verify`. Check `EdgeSpark routing` and `SSL` to see which step is still in flight.                                            |
| `active`   | Live and serving traffic with a valid certificate           | Visit the URL — traffic is on.                                                                                                                                                          |
| `failed`   | Setup hit a permanent error                                 | Read the warning in `edgespark domain status` (and the `error_message` field), fix the underlying issue (typo in records, CAA blocking issuance), and re-run `edgespark domain verify`. |
| `removing` | Detachment is in progress on the platform side              | Wait. `domain status` will flip to `removed`.                                                                                                                                           |
| `removed`  | Detachment completed                                        | The hostname is free for re-add via `edgespark domain add`.                                                                                                                             |

`status` and `verify` also surface a free-form `error_message` field when the platform has a specific reason for a non-active state.

## Apex versus subdomain

Both shapes work — the CLI prints the right records for each:

* **Subdomain** (`app.example.com`) — a `CNAME` record where the host is the full hostname.
* **Apex** (`example.com`) — the same `CNAME` record, but with `@` as the host. Your DNS provider must support **CNAME flattening at the apex** — Cloudflare, Route 53, DNSimple, Vercel DNS, and others do; some legacy registrars do not. If yours does not support flattening, choose a subdomain instead.

When in doubt, copy the records the CLI prints verbatim — they are what the platform expects.

## Troubleshooting

| Symptom                                                         | Likely cause                                                               | Fix                                                                                                                            |
| --------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `pending` after publishing records                              | DNS has not propagated, or an extra record is shadowing yours              | `dig app.example.com` and `dig TXT _edgespark-verify-<scoped>.app.example.com` to confirm what the world sees.                 |
| `pending` with `EdgeSpark routing: active` but `SSL` not active | Certificate issuance is in flight or blocked                               | Check for a restrictive `CAA` record on the apex; either add the EdgeSpark CA or remove the restrictive entry. Otherwise wait. |
| `failed` with a CAA mention in `error_message`                  | Existing `CAA` record blocks the certificate authority EdgeSpark uses      | Update the `CAA` record set, then `edgespark domain verify`.                                                                   |
| `verify` exits with status still pending after 15 minutes       | Slow registrar or large TTL                                                | Re-run with `--timeout 30m` (or longer). The domain stays attached between attempts.                                           |
| `Project ID required` (exit code 2)                             | Command was run outside a project directory or `edgespark.toml` is missing | `cd` into the project, or set `EDGESPARK_PROJECT_ID` for one-off runs.                                                         |

For platform-wide naming and quota limits, see [platform limits](/reference/limits).

## See also

<Columns cols={2}>
  <Card title="Deploy your project" icon="rocket" href="/guides/deployment">
    Ship a build and learn the default project URL the platform issues.
  </Card>

  <Card title="Environments" icon="layer-group" href="/concepts/environments">
    The current single-environment model and how custom domains fit it.
  </Card>
</Columns>
