domain
Getting started

Quickstart

Create one connection on your server and open the complete browser flow.

This example uses Next.js App Router. The same three boundaries apply in every framework: create on the server, bridge connection requests through your origin, then open the dialog in the browser.

1. Create a connection session

app/api/domain-session/route.ts
import { createDomain0PlatformClient } from 'domain0'
import { PlatformCreateConnectionInputSchema } from 'domain0/contracts'

const platform = createDomain0PlatformClient({
  baseUrl: 'https://domain0.dev/api/domain0/',
  apiKey: () => process.env.DOMAIN0_API_KEY!,
})

export async function POST(request: Request) {
  const input = PlatformCreateConnectionInputSchema.parse(await request.json())
  const { connection } = await platform.createConnection(input)
  const access = await platform.issueConnectionToken(connection.id, {
    origin: new URL(request.url).origin,
  })

  return Response.json({ connectionId: connection.id, ...access })
}

2. Add the same-origin bridge

app/api/domain0/[...path]/route.ts
import { forwardDomain0ConnectionRequest } from 'domain0/server'

async function forward(
  request: Request,
  context: { params: Promise<{ path: string[] }> },
) {
  const { path } = await context.params
  return forwardDomain0ConnectionRequest({
    request,
    path,
    upstreamBaseUrl: 'https://domain0.dev/api/domain0/',
  })
}

export const GET = forward
export const POST = forward

The helper allows only connection-scoped routes. It forwards the bearer token and exact origin, but never cookies, API keys, or unrelated headers.

3. Open Domain0 Connect

connect-domain.ts
import {
  ConnectionIdSchema,
  IssueConnectionTokenResponseSchema,
  createDomain0Client,
  domain0,
} from 'domain0'

const SessionSchema = IssueConnectionTokenResponseSchema.extend({
  connectionId: ConnectionIdSchema,
})

const response = await fetch('/api/domain-session', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    intent: {
      domain: 'customer.example',
      records: [
        {
          host: 'app',
          type: 'CNAME',
          value: 'edge.your-product.com',
          ttl: 300,
        },
      ],
    },
  }),
})
if (!response.ok) throw new Error('Domain session creation failed')

const session = SessionSchema.parse(await response.json())

const connectionId = ConnectionIdSchema.parse(session.connectionId)
const client = createDomain0Client({
  baseUrl: '/api/domain0/',
  token: session.accessToken,
})

await domain0.connectDomain({
  client,
  connectionId,
  applicationName: 'Your product',
  onSuccess: ({ connection }) => {
    console.log(`${connection.intent.domain} is active`)
  },
})

The dialog now owns provider detection, provider selection, authorization, change review, setup, and authoritative verification for that connection.

Authenticate your session endpoint

Protect /api/domain-session with your own user and tenant authorization. Validate that the signed-in user may connect the requested customer domain before calling Domain0.

On this page