Documentation

Custom domains

Serve your project on your own subdomain instead of the nulvless.co URL.

Every project answers on <project>.nulvless.co. On the Scale plan you can also serve the production environment on a subdomain you own, such as api.example.com. Paths do not change — /auth, /comms, /billing and your functions answer on the custom domain exactly as on the project URL — and the certificate is issued and renewed for you.

api.example.com ──CNAME──▶ acme.nulvless.co ──▶ your project (main)

Rules

subdomains onlyrule

api.example.com works; the apex example.com does not, because an apex cannot hold a CNAME.

one per projectrule

A project serves a single custom domain, and a domain belongs to a single project.

productionrule

The domain points at the main environment. Other environments keep their <project>-<environment>.nulvless.co URL.

Adding a domain

Add the hostname to the project, for example api.example.com. It starts as pending.

At your DNS provider, create the record shown for it:

Type   CNAME
Name   api
Value  acme.nulvless.co
Proxy  off

Wait for validation. Once the record resolves, the hostname is validated and its certificate issued — usually a few minutes, longer if your DNS has a high TTL. The domain turns active and starts serving.

Point your clients at it. The project URL is the first argument to createClient, so switching is a URL change:

const nulvless = createClient('https://api.example.com', 'pk-…')

Keep the record DNS only. If your DNS provider is also a proxy (for example, the orange cloud at Cloudflare), the proxy answers in front of us and validation cannot complete.

Social sign-in

Providers such as Google and GitHub send the user back to a callback URL on your project. While the domain is pending, that is the project URL. Once it turns active, sign-in returns to the custom domain instead:

before   https://acme.nulvless.co/auth/google/callback
after    https://api.example.com/auth/google/callback

A provider rejects a callback it does not know, so add the new URL at each provider you have enabled before the domain turns active, next to the one already registered. Each provider's page in the Console shows the callback in use, and switches to the custom domain once it is active.

Keep the project URL callbacks registered too. If the domain is removed, suspended or stops validating, sign-in returns to the project URL on its own.

Sign-in with OpenID Connect

The custom domain does not change your project's issuer. It stays https://<project>.nulvless.co/auth: that is the iss in every token and the base of every endpoint in the discovery document, whichever domain served it.

When you register your project as an OpenID Connect provider in another application, give it the project URL as the issuer, not the custom domain. Discovery requires the issuer in the document to match the URL it was fetched from, so a client configured with https://api.example.com/auth rejects it.

issuer       https://acme.nulvless.co/auth
your API     https://api.example.com

Statuses

pendingstatus

Waiting for the CNAME or the certificate. Not serving yet.

activestatus

Serving traffic on the custom domain.

failedstatus

Validation could not complete, or the hostname is in use elsewhere. Check the record, then remove the domain and add it again.

suspendedstatus

The organization's plan no longer includes custom domains. The domain stops serving but stays configured.

Changing plans

Moving below Pro suspends the domain: requests to it stop being served, while the project URL keeps working. Nothing is deleted. Upgrading back registers it again — it returns to pending and becomes active once validated, with the same DNS record.

A suspended domain can still be removed on any plan.

Errors

insufficient_plan403

The organization's plan does not include custom domains.

domain_invalid400

Not a subdomain: an apex, a wildcard or an invalid name.

domain_reserved400

A nulvless.co or nulvless.com name.

domain_limit_reached409

The project already has a custom domain.

domain_taken409

The hostname is already in use.

domain_unavailable503

Custom domains are temporarily unavailable. Try again in a moment.

On this page