/projects/{project_id}/branches/{branch_id}/custom-domainsRegister a custom domain on a branchRegisters a customer-owned domain (for example dashboard.acme.com) on the branch and points it at a target entity, chosen by entity_type + entity_id. In v1 only entity_type: function is supported (an unsupported type is rejected with 400), where entity_id is the function slug and the function must already exist on the branch (else 404).
The response includes the cname_target the customer must point their domain at with a CNAME record; the domain goes live only once that DNS resolves and a certificate is issued on the first request. A domain already registered to another resource is rejected with 409 and no detail about the owner. Re-registering the same domain for the same entity is idempotent.
Note: This endpoint is currently in Beta.
Parameters
project_idstringpathrequiredThe Neon project ID
branch_idstringpathrequiredThe Neon branch ID
Request body
requiredapplication/json
domainstringrequiredThe custom domain to register (for example `dashboard.acme.com`). Case-insensitive; normalized to lowercase (a trailing root dot is stripped, so the 254-char bound admits a fully-qualified name whose normalized form is 253 chars). Neon-managed and internal hostnames are rejected.
entity_idstringrequiredThe target entity's identifier within the branch. For `function` this is the function slug (which must already exist on the branch).
entity_typestringrequiredThe kind of branch entity to point the domain at. v1 supports only `function`; any other value is rejected with `invalid_entity_type`.
{
"domain": "string",
"entity_id": "string",
"entity_type": "function"
}Responses
binding_statusstringWhether Neon's internal routing for the domain is published: `pending`, `present`, or `missing`. `missing` is an internal fault surfaced for support. Not an `enum`.
cname_targetstringrequiredThe hostname the customer must point their custom domain at with a CNAME record. Empty when the serving region has no custom-domains front door configured. This is the activation input: point DNS here and the domain goes live (see `status`) once a certificate is issued on the first request.
dns_statusstringThe DNS + CAA portion of the check: `pending` (no records yet), `ok` (resolves to our edge and the CA is authorized), `misconfigured` (your CNAME does not resolve to our edge), or `caa_blocked` (your CAA records forbid Let's Encrypt). Not an `enum`.
domainstringrequiredThe registered custom domain (normalized, lowercase).
entity_idstringrequiredThe target entity's identifier within the branch. For `function` this is the function slug.
entity_typestringrequiredThe kind of branch entity the domain targets. Possible values: `function` (v1 supports only `function`). Not an `enum`: new values may ship in later spec versions — treat any undocumented value as unknown.
statusstringThe domain's current validity, computed by a background check: `pending` (still converging — point your CNAME at `cname_target` and wait), `active` (live: DNS resolves to the edge, the CA is authorized, and routing is published), or `error` (a fixable problem — see `status_reason`). Not an `enum`: treat any undocumented value as unknown. May be absent briefly right after registration.
status_reasonstringA short, stable machine-readable reason for a non-active `status` (e.g. `cname-not-pointing-at-edge`, `caa-blocks-lets-encrypt`, `binding-missing`), suitable for keying an actionable hint. Empty when active or pending.
{
"binding_status": "string",
"cname_target": "string",
"dns_status": "string",
"domain": "string",
"entity_id": "string",
"entity_type": "string",
"status": "string",
"status_reason": "string"
}codestringrequiredmessagestringrequiredError message
request_idstringUnique identifier for the request, useful for debugging. You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
{
"code": "",
"message": "string",
"request_id": "string"
}