Create domain
Attach a custom domain to an environment and start verifying it.
The domain is created in the pending state and does not serve traffic until verification succeeds. Verification runs in the background and polls DNS, so it is eventually consistent.
The response returns dnsRecords: every record needed to finish setup, already resolved for whether this domain is an apex or a subdomain. Create every entry exactly as given. One record establishes routing and one proves ownership, and both are needed: whether ownership can be inferred from the routing record depends on how your provider publishes it, and a name another workspace has already verified can only be claimed through the ownership record. Neither is knowable before the records exist.
When your DNS provider supports Domain Connect, the response also carries a domainConnect object; opening its url applies the same records at the provider in one step. The object is absent when the shortcut is unavailable.
Domains are unique per workspace, so the same name cannot be attached to two environments. Attaching a domain that already exists in your workspace returns a 409 conflict.
How many domains you may attach is set by your plan. Attaching one beyond that allowance returns a 403; upgrade the plan or remove a domain you no longer need.
Important: verification stops after 24 hours without the required DNS records, and the domain moves to failed.
Required Permissions
Your root key must have one of the following permissions:
environment.*.create_domain(to attach domains to any environment)environment.<environment_id>.create_domain(to attach domains to a specific environment)
Authorizations
Unkey uses bearer tokens for authentication. Public integrations use root keys, while the dashboard proxy uses short-lived JWTs. To authenticate, include the token in the Authorization header of each request:
Root keys have specific permissions attached to them, controlling what operations they can perform. Legacy permissions use tuple strings like api.*.create_key; resource permissions use Unkey Resource Names plus actions, like unkey:v1:ws_123:keyspaces/*#create_key.
Security best practices:
- Keep root keys secure and never expose them in client-side code
- Use different root keys for different environments
- Rotate keys periodically, especially after team member departures
- Create keys with minimal necessary permissions following least privilege principle
- Monitor key usage with audit logs.
Body
Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
3 - 255^[a-zA-Z0-9_-]+$"proj_1234abcd"
Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
3 - 255^[a-zA-Z0-9_-]+$"proj_1234abcd"
Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
3 - 255^[a-zA-Z0-9_-]+$"proj_1234abcd"
Fully qualified domain name to attach to the environment, without a scheme, port, or path. Must be unique across your entire workspace: the same name cannot be attached to two environments.
The name must sit under a registrable domain: 'api.acme.co.uk' is accepted, the public suffix 'co.uk' itself is not. Internationalized names may be sent in Unicode or Punycode form; either way the domain is stored and returned in its canonical form, lowercase ASCII with Unicode labels Punycode encoded, and the DNS records in the response use that form.
4 - 253"api.acme.com"
Response
Domain created and verification started. The domain is pending until the DNS records resolve.