Docs / For AI coding agents
For AI coding agents
A compact, complete brief for AI coding agents integrating Custom Domain API into a SaaS codebase. Contracts, invariants, and a step-by-step checklist.
Give this page to your coding assistant, or point it at
https://customdomainapi.com/docs/ai-agents.md. Everything an
integration needs is below, with links to the full pages.
Goal
Let each workspace (tenant) of a SaaS app serve the app on a hostname its
customer owns, such as forms.acme.com, over HTTPS.
Facts
- API base URL:
https://edge.customdomainapi.com/v1on the Free plan, otherwisehttps://<edge name>/v1. Auth:Authorization: Bearer <API key>. - OpenAPI:
https://edge.customdomainapi.com/v1/openapi.json. - Python SDK:
pip install custom-domain-sdk(custom_domain.Client,CustomDomainMiddleware,WorkspaceResolver,verify_webhook). - Customers CNAME their hostname to
edge.customdomainapi.comon Free. - Secrets the app needs (from app.customdomainapi.com, each shown once):
CUSTOM_DOMAIN_API_KEY,CUSTOM_DOMAIN_ASSERTION_SECRETwith its key id (app_…),CUSTOM_DOMAIN_APPLICATION_ID, and a webhook secret if webhooks are used. Read them from the environment; never commit them.
Invariants (do not break)
- Never select the tenant from the
Hostheader. Select it from the verifiedX-Custom-Domain-Assertion(reffield) only. See Verifying requests. - Verify the assertion before trusting it: HMAC-SHA256, key looked up by
id, constant-time compare,
exp/iatwith 30 s skew,appequals the application id,hostequals the request host. - Serve
GET /.well-known/custom-domain-workspacereturning{"reference": "<ref from the verified assertion>"}(404 if the workspace doesn’t exist). The domain can’t go live without it. - Store the domain
idwith the workspace; show the customer thedns_recordsexactly as returned. - Send
Idempotency-KeyonPOST /v1/domainsso retries are safe. - Treat webhooks as at-least-once and unordered: verify the signature,
dedupe on event
id, comparecreated_at. - Handle
409 hostname_already_claimed,409 domain_limit_reached,422 apex_not_supportedand the other 422 hostname codes with clear messages to the customer; respect429Retry-After.
Checklist
- Data model: add to the workspace (or a new table)
custom_hostname,custom_domain_id,custom_domain_status. - Settings UI: a field for the hostname. On save, call
POST /v1/domainswithhostnameandreference= the workspace id; storeidandstatus; render the twodns_recordswith copy buttons. - Status: show
statusand each failing check’smessage. A “check again” button callsPOST /v1/domains/{id}/checks. - Updates: subscribe to
domain.ready,domain.attention_required,domain.recoveredanddomain.deleted(POST /v1/webhooks), and update the stored status in the handler; or pollGET /v1/domains/{id}. - Removing:
DELETE /v1/domains/{id}when the customer removes the hostname or the workspace is deleted. - Request routing: add the assertion verification middleware; map
refto the workspace for every request that carries the header. Requests on the app’s own domain (no header) keep their existing routing. - Absolute URLs: build them from the request’s
HostandX-Forwarded-Proto; the edge sets both to the customer-facing values. Cookies should not set aDomainattribute bound to the app’s own domain. - Tests: a forged or expired assertion is refused; a valid one selects the
right workspace;
Hostalone never selects a workspace.
Full pages
Quickstart · How it works · API reference · Verifying requests · Webhooks · Your customers’ DNS