Connect Domain
Getting started

Quickstart

Connect your first custom domain end to end in about five minutes.

Connect your first custom domain end to end in about five minutes. This uses the API directly; to embed the UI instead, see The widget SDK.

0. Run the stack (local)

cd app
make dev     # boots Postgres + control-plane + edge + demo, prints URLs

The control-plane listens on http://localhost:8080. A demo application and API key (sk_test_demo) are seeded. For real deployments see Self-hosting.

1. Create an application

An application is your product surface. It carries the record template new connections inherit and the allowed embed origins.

curl -X POST http://localhost:8080/v1/applications \
  -H "Authorization: Bearer sk_test_demo" \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme Sites","allowed_origins":["https://app.acme.example"]}'

Creating applications and keys requires a key with the apps:admin scope — see Authentication.

2. Create an API key

curl -X POST http://localhost:8080/v1/applications/<APP_ID>/keys \
  -H "Authorization: Bearer sk_test_demo" \
  -H "Content-Type: application/json" \
  -d '{"name":"server-prod","scopes":["connections:read","connections:write"]}'

The secret is returned once — store it now; it's kept only as a hash. A key can never grant scopes the calling key doesn't itself hold.

3. Start a connection

curl -X POST http://localhost:8080/v1/connections \
  -H "Authorization: Bearer <YOUR_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"application_id":"<APP_ID>","hostname":"app.customer.com"}'

The response includes the connection id (also the jobId), the desired DNS records, and an ownership_challenge — a TXT record the customer must publish to prove control:

{
  "id": "…",
  "state": "pending_ownership",
  "ownership_challenge": { "name": "_customdomain-challenge.app.customer.com", "type": "TXT", "value": "cd-verify-…" }
}

If the application has a stored delegated DNS credential, the records (and no manual step) are written automatically and the connection jumps straight to propagating — you can skip to step 6.

4. Publish DNS

The customer adds, at their DNS provider:

  • The ownership TXT from the challenge.
  • The desired records (returned on the connection) pointing the hostname at the edge.

5. Verify ownership

curl -X POST http://localhost:8080/v1/connections/<ID>/verify \
  -H "Authorization: Bearer <YOUR_KEY>"

On success the connection moves to verified, which opens the edge ask gate. (The background worker also does this automatically once the TXT is visible.)

6. Watch propagation → live

curl -X POST http://localhost:8080/v1/connections/<ID>/records:check \
  -H "Authorization: Bearer <YOUR_KEY>"

When every desired record resolves to its intended value, the connection becomes live, the certificate is issued on the next TLS handshake, and the edge starts proxying https://app.customer.com to your origin. You'll receive ssl.issued and domain.flow.completed webhooks.

Next steps

On this page