Skip to main content

Custom Domain

Custom domains let you serve the Frost Auth API from your own subdomain instead of the default host. This is useful when ISPs block requests to shared API infrastructure, or when you want your clients hitting a domain you control.
Custom domains are for the API only. The customer panel (/panel/:owner/:product) always runs on the main FrostAuth host and cannot be mapped to a custom domain.
Custom domains require the Pro plan. Starter and Developer plans do not include this feature.

How it works

You point a CNAME record at cname.frostauth.cc, save the hostname in your product settings, then verify it. Once verified, the domain is added to the CORS allow-list and the edge TLS terminator begins issuing a certificate for it. Your SDKs and client apps then use https://your-domain/api/v1 as their base URL instead of the default.

Setup

Step 1 — Navigate to Settings

Open the console, select your product, and go to Settings → Custom Domain.

Step 2 — Enter your subdomain

Type the hostname you want to use (e.g. api.yourdomain.com).
  • Use a bare hostname — no https://, no port, no path.
  • The input is lowercased and trimmed automatically.
  • The domain must be unique across all Frost Auth products. If another operator already claimed it, the save will fail.
Click Save Changes to store it.
Changing an existing domain resets its verification status. You must re-verify after every change.

Step 3 — Create the CNAME record

At your DNS provider, add a CNAME record: The target value (cname.frostauth.cc) is shown in the dashboard under the domain input. Copy it directly rather than typing it.

Step 4 — Verify

Click the Verify button in the Custom Domain tab. The server performs a live DNS CNAME lookup against your hostname and checks whether it resolves to cname.frostauth.cc.
  • Verified — the CNAME matches. The domain is added to the CORS allow-list within 60 seconds (the cache refresh interval).
  • Not verified yet — the CNAME either doesn’t exist yet or points somewhere else. DNS propagation can take up to an hour. Do not keep clicking verify in a loop; wait and try again.
Verification proves the CNAME points at us. It does not mean traffic will flow immediately — the edge also needs to hold a TLS certificate for the hostname before HTTPS connections succeed.

Step 5 — Update your SDK base URL

Once verified, the dashboard shows your new SDK base URL:
Replace the default API URL in your application with this value. In the official SDKs, pass it as the base URL parameter during initialization.

Responses

Save domain (PATCH /api/v1/settings/:productId)

Verify domain (POST /api/v1/settings/:productId/domain/verify)


Errors


Behavior

  • DNS verification is a live lookup, not a poll. Each click of Verify triggers one resolveCname call. There is no background polling loop.
  • Changing the domain resets verification. Any PATCH that includes domain sets domainVerified: false and domainCheckedAt: null. The old domain stops being trusted on the next cache refresh (within 60 seconds).
  • CORS trust is cached. Verified domains are held in an in-memory Set per instance, backed by a Redis cache with a 60-second TTL. After verification succeeds, the cache is explicitly invalidated so other instances pick it up on their next tick rather than waiting out the window.
  • Only HTTPS origins are accepted. The CORS check parses the origin URL and refuses any protocol other than https:. A custom domain without TLS would send session cookies in clear text.
  • TLS certificates are separate from verification. Verification proves the CNAME points at FrostAuth. Serving traffic also requires the edge to hold a certificate for the hostname. The edge’s on-demand TLS hook calls GET /settings/domain/issuable?domain=... before issuing one — if your domain is verified, it answers 200 and the certificate is minted. Until that happens, HTTPS connections to your domain will fail even though the dashboard says verified.
  • Domain uniqueness is platform-wide. Two products across different accounts cannot share the same custom domain. The database enforces this with a unique constraint.
  • Revoking a domain (clearing the field) removes it from the verified set on the next cache refresh. Requests to the old domain will start receiving CORS refusals once the cache expires.