Getting started
From signup to a verified custom domain — create an app, mint a connect session, and receive the signed webhook.
1. Sign in and create an app
Create your account at app.dodomain.io/signin?mode=signup — with Google or with email and password. Every account gets a personal team, and the free plan needs no card.
Create an app in the dashboard. You get two keys:
- Public key (
dd_pk_...) — identifies the app in the widget; safe to expose, grants nothing. - Secret key (
dd_sk_...) — authenticates your server's API calls. It is shown once and stored only as a hash; keep it server-side, never in a browser bundle. You can rotate it from the dashboard if it leaks.
2. Mint a connect session
One call from your server. Describe the records your product needs on the user's domain — host is relative to the domain ("app" becomes app.customer.com; use "@" for the apex), and value is where the record points.
curl -X POST https://app.dodomain.io/api/v1/sessions \
-H "Authorization: Bearer dd_sk_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "customer.com",
"records": [
{ "type": "CNAME", "host": "app", "value": "edge.yourproduct.com" },
{ "type": "TXT", "host": "_yourproduct", "value": "yourproduct-verify=7f3a9c" }
],
"returnUrl": "https://yourproduct.com/settings/domains"
}'The response is a short-lived session (24-hour expiry):
{
"id": "cmcwl0d9x0001…",
"token": "dd_sess_Qy3v…",
"expiresAt": "2026-07-12T14:03:07.000Z",
"connectUrl": "https://app.dodomain.io/connect/dd_sess_Qy3v…"
}3. Send your user to the connect flow
Open connectUrl — link, redirect, or new tab. The hosted page detects the user's DNS provider: on Cloudflare it offers one-click apply via OAuth; everywhere else it shows provider-specific copy-paste instructions with live per-record verification. Prefer it embedded? The @dodomain/connect widget opens the same flow in a modal on your own page.
4. Receive the signed webhook
Add a webhook endpoint for your app in the dashboard — you get a whsec_... signing secret. The moment the records verify against authoritative DNS, DoDomain POSTs a connection.verified event to it. Verify the signature (header x-dodomain-signature, format t=<unix ms>,v1=<hex HMAC-SHA256>), then activate the domain in your product.
Or use a server SDK
@dodomain/node and dodomain-sdk wrap all of this — a
schema-validated sessions.create plus a webhook verifier, over the same shapes. The raw HTTP
above stays fully supported; the SDKs are a convenience, not a requirement.
import { DoDomain, verifyWebhook } from "@dodomain/node";
const dodomain = new DoDomain({ secretKey: process.env.DODOMAIN_SECRET_KEY });
const session = await dodomain.sessions.create({
domain: "customer.com",
records: [{ type: "CNAME", host: "app", value: "edge.yourproduct.com" }],
});
// session.connectUrl → hand to your user
// verifyWebhook(secret, rawBody, signatureHeader) → booleanThe same two steps in Python:
import os
from dodomain import DoDomain, DnsRecord, verify_webhook
client = DoDomain(secret_key=os.environ["DODOMAIN_SECRET_KEY"])
session = client.sessions.create(
domain="customer.com",
records=[DnsRecord(type="CNAME", host="app", value="edge.yourproduct.com")],
)
# session.connect_url → hand to your user
# verify_webhook(secret, raw_body, signature_header) → bool