Docs / Quickstart
Quickstart
Let a customer of your SaaS use their own hostname in about fifteen minutes on the Free plan, from sign-up to HTTPS, with the API and the Python SDK.
This guide takes one customer hostname from nothing to live over HTTPS, on the Free plan. You need a backend reachable on the internet over HTTPS (your origin), and a way to run a few lines of code.
1. Start Free
Sign in at app.customdomainapi.com with your email, open Free and start. No card is needed. Your application is set up in a few seconds.
On Free, your customers point their hostnames at:
edge.customdomainapi.com
and your backend calls the API at:
https://edge.customdomainapi.com/v1
2. Add and verify your origin
On the Origin tab, add your backend’s hostname, for example
app.yourproduct.com. The page shows a token and a URL. Make your origin
answer that URL with exactly the token as a plain-text body:
GET https://app.yourproduct.com/.well-known/custom-domain-origin-verification
→ 200, body: <the token>
Then press Verify and use. Traffic for your customers’ hostnames goes to this origin from now on.
3. Get your assertion key
On the same tab, press Get your assertion key. You see, once:
- the key id (it starts with
app_), - the secret,
- your application id.
Store the secret with your origin’s secrets. Every request the edge forwards
carries an X-Custom-Domain-Assertion header signed with this key; your
origin verifies it and selects the workspace from it (step 6).
4. Create your API key
On API keys, create your key. It is shown once. Free includes one key,
which may make 60 requests a minute. Store it in your backend’s secrets, for
example as CUSTOM_DOMAIN_API_KEY.
5. Register a customer’s hostname
When a customer enters their hostname in your product, register it for their workspace:
curl -X POST https://edge.customdomainapi.com/v1/domains \
-H "Authorization: Bearer $CUSTOM_DOMAIN_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: signup-ws_8f3a1c" \
-d '{"hostname": "forms.acme.com", "reference": "ws_8f3a1c"}'
Or with the Python SDK (pip install custom-domain-sdk):
from custom_domain import Client
client = Client("https://edge.customdomainapi.com", credential=CUSTOM_DOMAIN_API_KEY)
domain = client.create_domain(
"forms.acme.com", # the customer's exact subdomain
reference="ws_8f3a1c", # your workspace id; it comes back on every request
idempotency_key="signup-ws_8f3a1c",
)
print(domain.render_dns_instructions())
The response contains dns_records: one TXT record that proves the
customer owns the name and one CNAME that sends its traffic to the edge.
Show both to your customer exactly as returned (see
Your customers’ DNS).
6. Verify requests at your origin
Your origin must select the workspace from the verified assertion, never from
the Host header. With the Python SDK in FastAPI or Starlette:
import os
from custom_domain import CustomDomainMiddleware
app.add_middleware(
CustomDomainMiddleware,
keys={"app_…": os.environ["CUSTOM_DOMAIN_ASSERTION_SECRET"]}, # your key id and secret
application_id="…", # your application id
workspace_lookup=load_workspace, # returns the workspace for a reference, or None
)
@app.get("/")
def home(request):
workspace = load_workspace(request.state.custom_domain.reference)
The middleware also answers GET /.well-known/custom-domain-workspace, which
the service calls through the edge to prove that the hostname reaches the
right workspace before it goes live. Other languages: see
Verifying requests.
7. Wait for ready
Once your customer has published the records, the service checks ownership,
routing, the certificate and your origin. When all four pass, the domain’s
status becomes ready and the hostname is served over HTTPS. Poll
GET /v1/domains/{id}, or subscribe to the domain.ready
webhook. If your customer fixes a record, ask for an early
re-check with POST /v1/domains/{id}/checks.
That’s it. Repeat step 5 for every customer hostname, up to 25 on Free.