POST/projects/{project_id}/branches/{branch_id}/custom-domains

Register a custom domain on a branch

Registers 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.

  • IdempotentThe SDK sends Idempotency-Key, so a retried request is only applied once.

2 parameters · 3 body fields
project_idstringrequired
The Neon project ID
branch_idstringrequired
The Neon branch ID
domainstringrequired
The 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_typestringrequired
The kind of branch entity to point the domain at. v1 supports only `function`; any other value is rejected with `invalid_entity_type`.
entity_idstringrequired
The target entity's identifier within the branch. For `function` this is the function slug (which must already exist on the branch).

2 status codes
201The registered custom domain
domainstringrequired
The registered custom domain (normalized, lowercase).
entity_typestringrequired
The 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.
entity_idstringrequired
The target entity's identifier within the branch. For `function` this is the function slug.
cname_targetstringrequired
The 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.
statusstringoptional
The 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.
dns_statusstringoptional
The 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`.
binding_statusstringoptional
Whether Neon's internal routing for the domain is published: `pending`, `present`, or `missing`. `missing` is an internal fault surfaced for support. Not an `enum`.
status_reasonstringoptional
A 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.
defaultGeneral Error. The request may or may not be safe to retry, depending on the HTTP method, response status code, and whether a response was received. - If no response is returned from the API, a network error or timeout likely occurred. - In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results. The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**. The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout. Any request that returns a `503 Service Unavailable` response is always safe to retry. Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.
request_idstringoptional
Unique 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.
codestringrequired
Machine-readable code classifying the error type. See `message` for a human-readable explanation.
Default:
messagestringrequired
Error message

Error handling

Any other status is an error: General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code, and whether a response was received.

  • If no response is returned from the API, a network error or timeout likely occurred.
  • In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: POST, PATCH, DELETE, and PUT. Retrying these methods is generally not safe. The following methods are considered idempotent: GET, HEAD, and OPTIONS. Retrying these methods is safe in the event of a network error or timeout.

Any request that returns a 503 Service Unavailable response is always safe to retry.

Any request that returns a 423 Locked response is safe to retry. 423 Locked indicates that the resource is temporarily locked, for example, due to another operation in progress.