We ran the same workload through 42 models via AI Gateway and compared costs
/APIs & SDKs/Functions/Register a custom domain on a branch
POST/projects/{project_id}/branches/{branch_id}/custom-domainsbeta

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.

Markdown for AI context

Quick start

REST API - curl
curl "https://console.neon.tech/api/v2/projects/$PROJECT_ID/branches/$BRANCH_ID/custom-domains" \
  -X POST \
  -H "Authorization: Bearer $NEON_API_KEY"
Also available in
import { createNeonClient, raw } from '@neon/sdk';

const neon = createNeonClient({ apiKey: process.env.NEON_API_KEY });
const { data } = await raw.registerProjectBranchCustomDomain({
  client: neon.client,
  path: {
    project_id: process.env.PROJECT_ID,
    branch_id: process.env.BRANCH_ID
  }
});

Parameters

Project ID
project_id
string

The Neon project ID

Branch ID
branch_id
string

The Neon branch ID

Request body

3 required Required: domain, entity_type, entity_id.

Domain
domain
string

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.

≥3 chars, ≤254 chars

Entity type
entity_type
string

The kind of branch entity to point the domain at. v1 supports only function; any other value is rejected with invalid_entity_type.

≥1 chars, ≤32 chars

Entity ID
entity_id
string

The target entity's identifier within the branch. For function this is the function slug (which must already exist on the branch).

≥1 chars, ≤255 chars

Response

201

The registered custom domain

Depth
"domain": (string),req
"entity_type": (string),req
"entity_id": (string),req
"cname_target": (string),req
"status": (string),
"dns_status": (string),
"binding_status": (string),
"status_reason": (string),

Errors

default

General error

This endpoint can return the standard Neon API error response.

Response fields

  • message Required. Human-readable error message.
  • code Required. Machine-readable error code.
  • request_id Optional. Request identifier for debugging. You can provide one with the X-Request-ID header.

Retry guidance

If no response is returned, the request may still have reached the server. This is why retry safety depends on the method and status code.

Idempotent methods (GET, HEAD, OPTIONS) are generally safe to retry after a network error or timeout. Non-idempotent methods (POST, PATCH, DELETE, PUT) can change state, so avoid automatic retries unless your workflow can tolerate duplicate effects.

Responses with 423 Locked or 503 Service Unavailable are safe to retry. 423 Locked means the resource is temporarily locked, usually because another operation is in progress.

Was this page helpful?

On this page

Copy neon init command