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

# Custom Domain

> Serve verification and OIDC from your own branded domain instead of the default Hopae URLs.

By default, your users see Hopae-hosted URLs during verification. A **custom domain** lets you serve the hosted verification UI and the OIDC backend from your own branded hostnames instead, so the whole flow stays on your brand.

## The two hosts

A custom domain configures **two** hostnames, and they play different roles:

| Host                 | Field        | Replaces                                 | Serves                                                |
| :------------------- | :----------- | :--------------------------------------- | :---------------------------------------------------- |
| **Web Frontend URL** | `webDomain`  | The default Hopae-hosted verification UI | The hosted UI your users open during verification     |
| **OIDC Backend URL** | `oidcDomain` | The default Hopae OIDC endpoint          | The OIDC backend (issuer, authorize, token, userinfo) |

<Warning>
  The two hosts **must be different** from each other and **must share the same base domain**. For example, `verify.example.com` (web) and `connect.example.com` (oidc) are both under `example.com` — valid. Using the same host for both, or hosts on different base domains, is rejected.
</Warning>

## Status and lifecycle

A custom domain moves through a small set of states. You can read the current state at any time and show it in your own UI.

| Status         | What it means                                                                                                              |
| :------------- | :------------------------------------------------------------------------------------------------------------------------- |
| `unconfigured` | No custom domain is set. This is where every app starts.                                                                   |
| `awaiting_dns` | You submitted the two hosts and the DNS records are ready. Add **all** of them at your DNS provider, then verify.          |
| `verifying`    | Records were detected and ownership is being confirmed; the SSL certificate is being issued.                               |
| `active`       | The certificate is issued and your domain is **live**, serving the verification UI and OIDC backend.                       |
| `invalid`      | Something needs fixing (for example, a missing or incorrect record, or a configuration conflict). Fix it and verify again. |

```mermaid theme={null}
stateDiagram-v2
    direction LR
    [*] --> unconfigured
    unconfigured --> awaiting_dns: configure (PUT)
    awaiting_dns --> verifying: records detected
    verifying --> active: SSL issued + live
    awaiting_dns --> invalid: check failed
    verifying --> invalid: check failed
    invalid --> verifying: fix + verify
    active --> [*]
```

## Verified vs. active

Two milestones are easy to confuse:

* **Verified** — your DNS records are in place and Hopae has confirmed you control the domain. This is the `verifying` checkpoint passing.
* **Active** — the SSL certificate has been issued and the domain is **live and serving traffic**. This is the `active` status.

<Info>
  A domain can be **verified but not yet active**: ownership is confirmed (`verifying`) while the SSL certificate is still being issued. Only rely on the domain once it reaches `active`.
</Info>

## DNS records

When you configure a custom domain, Hopae gives you a set of DNS records to add at your DNS provider. **Add every record shown, for both hosts** (web and OIDC) — the domain only goes `active` once they are all in place. The records fall into three kinds:

| Record                           | Purpose                                                                                                                          |
| :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| **Routing** (`CNAME`)            | Points each host (web and OIDC) to Hopae so requests are routed to us.                                                           |
| **Ownership** (`TXT`)            | Proves you control the domain.                                                                                                   |
| **SSL / DCV** (`CNAME` or `TXT`) | Lets the certificate authority validate your domain so it can issue the SSL certificate — Hopae manages the certificate for you. |

<Warning>
  Partial records are not enough. If any record is missing, verification stays at `awaiting_dns` or `verifying` and the domain never reaches `active`. Add **every** record shown for **both** the web and OIDC hosts.
</Warning>

## How status advances

Status only changes when **you trigger a verify**. There is **no background polling and no webhooks** for custom domain status — Hopae does not re-check your DNS on its own.

* After you add the DNS records, call the verify action ([`POST .../custom-domain/verify`](/api-reference/workspace/verify-custom-domain)).
* Each verify re-checks DNS and SSL and returns the updated state.
* Repeat verify (poll) until the status reaches `active`.
* Reading the domain with [`GET .../custom-domain`](/api-reference/workspace/get-custom-domain) is **read-only** — it returns the stored state but never advances it.

<Info>
  In the Console, the custom domain screen calls verify for you on a short interval and when you click **Refresh**. If you integrate directly against the Workspace API, you own the polling — call verify until the status is `active`.
</Info>

## See also

* [Get Custom Domain](/api-reference/workspace/get-custom-domain) — read the current state (read-only).
* [Configure Custom Domain](/api-reference/workspace/update-custom-domain) — set the web and OIDC hosts.
* [Verify Custom Domain](/api-reference/workspace/verify-custom-domain) — re-check DNS/SSL and advance status.
* [Delete Custom Domain](/api-reference/workspace/delete-custom-domain) — remove the custom domain.
