CustomDomain Docs

Reference

Lookup tables for CustomDomain™: enums, DNS record types, webhook events, error codes, environment variables, webhook signatures and the default edge record.

Enums

ConnectionStatus: pending, propagating, live, failed.

SetupType: automatic, manual, async, mcp.

Role: owner, admin, member, viewer.

PlanId: starter, startup, growth, premium, enterprise (and free, retired on 2026-09-29: it still names a legacy workspace moving to a paid plan, and is never offered).

BillingState: trialing, active, past_due, grace, blocked, comped, canceled, legacy_free (see Plans & quotas).

Environment: production, staging, development.

DNS record types: A, AAAA, CNAME, CAA, MX, NS, SRV, TXT, plus the meta-types SPFM (SPF-merge), APEXCNAME (a CNAME at the zone root, realized per provider) and REDIR301.

One-click setup template shapes (the provider-hosted one-click protocol; customdomain.ai catalog shipped in prod): web: apex-a, apex-aaaa, apex-cname, apex-www, subdomain, www, wildcard, customdomain, website, clickfunnels; ownership: verify, connect-verified (apex A + ownership TXT applied together); caa; email: email-spf, email-dkim, email-dmarc, email-mx, email-full; and redirect (301 forward).

Webhook events (the complete set; see webhooks): connection.created, connection.applied, connection.live, connection.failed, connection.records.updated, connection.reapply.failed, connection.records_outdated, connection.disconnected, domain.record_missing, domain.record_restored, domain.purchased, purchase.error, purchase.confirmation.expired, secure_status, power_status, certificate.issued, certificate.renewed, certificate.failed, certificate.expiring.

Error envelope & codes

Every error is { "code", "title", "details"? }. code is a stable machine string:

codeHTTPMeaning
invalid_request400Malformed or missing input.
unauthorized401Missing/invalid credential.
forbidden403The credential is valid but may not do this (a role or scope too low).
not_found404Object doesn't exist or isn't in your tenant.
conflict409The request conflicts with the resource's current state.
rate_limited429Too many requests; slow down and retry shortly.
reach_quota429The workspace has made as many reads at DNS providers, to find out what a key reaches, as it may this hour. Retry-After is the seconds until the hour ends. See provider accounts.
billing_required402The workspace has no active subscription or trial, so new connections and new credentials (API keys, applications, rotated secrets) are refused (existing ones keep working). A new workspace's first ten domains (its free domains) are the exception: they connect without a card, and the next one is refused. details says why and where an owner or admin can fix it. See Plans & quotas.
connections_unavailable402The same refusal as the tenant's end users see it, with a neutral message that says nothing about the tenant's billing or account. A connect-scoped widget token (your customer in the widget) gets it in place of billing_required, quota_exceeded and workspace_suspended.
quota_exceeded402A Starter workspace connected its allowance of 10 domains in any 12 months (only where the deployment enforces quotas).
workspace_suspended403CustomDomain™ support suspended the workspace. New connections, every connect step on a domain it already has (a key apply, a provider sign in, one-click setup, the Route 53 access role, the hosted zone and :reapply) and the start of a domain purchase are refused. Reads, rechecks and removals keep working, and connected domains keep their records. Only support can resume the workspace.
sandbox_not_allowed403A test mode application's key or widget token, or a test mode domain, was used on something outside the test flow (SSL, Power, sign in, bulk, agents, purchases and the rest). details names what was refused.
sandbox_domain_required400A test mode application was given a name that does not end in .test.
sandbox_domain_reserved400A live application was given a .test name. Those are for test mode.
sandbox_limit409The test mode allowance is used up: 3 test mode applications per workspace, 100 test domains per application.
service_unavailable503An optional engine (Sell, templates, billing, webhooks) isn't configured.
internal_error500Server error (generic title + a logged request id).

Environment variables

Control-plane variables read CUSTOMDOMAIN_* first and fall back to the legacy JUSTEASY_* prefix. Variables that matter for API consumers are called out on the page that uses them.

Webhook signature

  • Headers: X-JE-Timestamp: <unix seconds> and X-JE-Signature: sha256=<hex>.
  • Algorithm: HMAC-SHA256 over ${timestamp}.${rawBody} (the timestamp, a dot, then the exact request body), keyed by the endpoint's signing secret (whsec_…). Reject deliveries whose timestamp is outside a ~5-minute window. See Verifying signatures.

Default edge record

A connection with no applied records yet points at the edge with a synthesized CNAME <host> → edge.customdomain.ai (TTL 3600), overridable with JUSTEASY_EDGE_CNAME_TARGET. At a zone root the record is realized per provider (ALIAS/ANAME/flattened CNAME, or A records to the edge IPs); see Root domains.

Resources

  • Architecture: the two-plane design, data model, and request flows.
  • openapi-v1.yaml: the OpenAPI document the API reference is generated from; also served live at GET /v1/openapi.json.

On this page