# Custom domains

Serve an environment's APIs (`/rest/v1`, `/auth/v1`, `/storage/v1`,
`/functions/v1`, `/realtime/v1`) from a hostname you own, such as
`api.example.com`. Custom domains are included in your plan.

## Add a domain

1. In the console, open **Settings > Domains** and add the hostname and the
   environment it serves.
2. Add the two records the page shows at your DNS provider:
   - a **CNAME** from your hostname to the target shown;
   - a **TXT** record at `_scribase-challenge.<your hostname>` that proves
     you own it.
3. That's it. The page checks the records by itself and moves through
   **Pending**, **Verified** and **Certificate live**, with the certificate's
   real expiry date.

For an apex domain (`example.com`) use your provider's CNAME flattening
(ALIAS/ANAME); the check accepts a domain that resolves to the same
addresses as the target.

## How the certificate is issued

The certificate comes from Let's Encrypt on the first secure request to your
hostname once the DNS records are visible. Before
it is ordered, the project router asks the control plane whether the
hostname is a verified custom domain; any other name gets no certificate,
and these asks are rate-limited. Renewals are automatic.

## API

- `POST /v1/organizations/{org}/projects/{project}/domains` with
  `{"domain", "environment_id"}` adds a domain and returns both records.
- `POST .../domains/{domain}/verify` checks it: ownership, where the domain
  points (`dns_target_ok`) and the certificate being served
  (`certificate_state`, `certificate_expires_at`). A missing TXT record
  answers `409 verification_record_missing`.
- `DELETE .../domains/{domain}` removes it.

## Passkeys

When an environment has passkeys on, its verified custom domains join the
passkey origins automatically (see
[Passkeys, MFA and SAML](https://docs.scribase.com/docs/concepts/auth-security.md)).
