A verified domain is a domain (e.g.Documentation Index
Fetch the complete documentation index at: https://docs.kayle.id/llms.txt
Use this file to discover all available pages before exploring further.
acme.co) that you’ve proved your organization controls. Verifying a domain unlocks the user-facing trust signals in the verify flow and is required before you can register custom redirect URIs.
End users see the verified domain rendered prominently in the verify dialog, alongside your organization name. Without a verified domain, Kayle ID hides your logo, legal name, jurisdiction, and registration number from end users — those fields are user-supplied and could be set to anyone, so we don’t surface them until we’ve confirmed who runs the organization.
Why this exists
Anyone can sign up to Kayle ID and create an organization called “Wells Fargo”. Without a verification step, end users would have no way to tell a legitimate Wells Fargo verify link from one a phishing actor sent over SMS. Domain verification anchors your organization’s identity in something an attacker can’t forge: control of DNS for the domain you actually operate from.Who can verify a domain
Only organization owners can start, complete, or remove a domain verification. Admins and members can view the verified-domain list but can’t change it. We ask for the highest role here because a verified domain unlocks branding shown to your users — taking that decision out of the hands of one-off teammates is intentional.Verifying a domain
- Go to Domains in the dashboard sidebar.
- Click Add domain.
-
Enter the bare domain you want to verify — for example
acme.co, not a subdomain likeapp.acme.co. Verifying a domain unlocks every subdomain underneath it. -
Add the TXT record we show you to the domain’s DNS. The record looks like:
Field Value Name _kayle-id-verification.<your-domain>Type TXTValue kayle-id-verification=<token> - Click Verify now once your DNS provider has published the record. We resolve it via DNS-over-HTTPS, so the propagation window is whatever your DNS provider takes — typically a few minutes for major providers.
DNS_NOT_PROPAGATED. The challenge stays valid for 7 days; you can come back and re-click Verify now as many times as you need within that window.
Why DNS, not email
We only support DNS TXT verification. The alternative — sending a one-time code toadmin@<your-domain> (or postmaster@, webmaster@, etc., per RFC 2142) — sounds easier but materially weakens the proof. Anyone who can read the inbox of a long-lived shared alias can pass the challenge, and those aliases are often misconfigured, forwarded to former employees, or unmonitored. DNS TXT proves you can publish records on the domain itself, which is the same level of control an attacker would need to actually impersonate your service.
What verification unlocks
Once a domain is verified for your organization:- Trust anchor in the verify flow. End users see “verified domain:
<your-domain>” in the dialog they open from your organization name. - Self-asserted business fields are revealed. Your legal name, jurisdiction, registration number, and uploaded logo (set on Public details) become visible to end users. Until then they’re stored but hidden.
- Custom redirect URIs become available. You can register specific URL patterns under Allowed redirect URIs for sessions you create.
Re-verification and downgrades
Kayle ID re-checks each verified domain’s TXT record once a day. If we can’t find the record on three consecutive checks (≈ 3 days), the domain is downgraded: it’s marked inactive, your business fields and logo are hidden again, and any session redirect URL on that domain is rejected. Owners receive an email when a downgrade happens. If the record reappears on a later check, the domain is automatically restored — you don’t need to do anything. To re-verify manually, open the Domains page and click Add domain again with the same domain.Verifying a domain another organization owns
A given domain can only be actively verified by one organization at a time. When you start a DNS challenge for a domain that another organization is currently verified for, Kayle ID surfaces aconflict field on the start-challenge response and the dashboard shows you a warning before you continue:
This domain is already verified elsewhere.If you proceed and pass the DNS check, Kayle ID atomically transfers the domain to your organization in the same transaction:acme.cois currently verified byOriginal Owner. If you complete the DNS challenge, their verification will be removed and your organization will become the active owner.
- The previous owner’s row is downgraded (
downgraded_atis set), so they immediately stop showing as the verified domain in the verify flow and lose redirect-URI authorization on this domain. - Your row is inserted (or, if you previously held a downgraded row for this domain, restored).
- The previous owner’s owner-role members receive an email letting them know the domain was transferred.
acknowledge_takeover: true on POST /v1/auth/orgs/domains/challenges/dns/verify) to confirm. The dashboard does this automatically once you click “I understand — continue” on the warning step.
If you believe a takeover is malicious — for example, an attacker is impersonating your brand — contact Kayle ID support immediately so we can investigate and reverse it.
Removing a domain
Click Remove next to the domain on the Domains page and confirm. Removal is immediate and:- hides the verify-flow trust signal for that domain;
- deletes any redirect URI patterns registered under it (cascades from the domain row);
- frees the domain so you can re-verify it later if you change your mind.
Allowed redirect URIs
By default, any subdomain or path on a verified domain is accepted as a sessionredirect_url. So if you’ve verified acme.co, you can pass https://app.acme.co/oauth/callback, https://id.acme.co/, or https://acme.co/done when creating a session and Kayle ID will accept all of them.
Add explicit entries on the Allowed redirect URIs card to narrow that default. Once one or more patterns exist for a verified domain, redirects on that domain must additionally match one of the registered patterns by path-prefix. URLs that don’t match any pattern are rejected with REDIRECT_URL_PATTERN_NOT_REGISTERED.
A pattern is composed of three parts:
- Subdomain (optional) — empty registers the domain itself;
appregistersapp.<domain>;app.idregisters a deeper subdomain. - Domain — picked from your verified domains.
- Path (optional) — must start with
/. Query strings (?) and fragments (#) are not allowed.
https://[subdomain.]<domain>[/path] — e.g. https://app.acme.co/oauth/callback. The dashboard shows you a live preview before you save.
Why query strings aren’t allowed
Patterns are matched as a strict path-prefix against incomingredirect_url values. Allowing query strings would either over-match (anyone passing the same path with extra params would match) or under-match (only that exact query would match). Neither is useful, so we reject both up front and let the path matching do the heavy lifting.
Edge cases and known behaviour
- What “domain” means here. Internally Kayle ID normalizes whatever you enter to the registrable domain (eTLD+1) — so
app.acme.cocollapses toacme.co, andacme.co.ukis preserved as a single unit. Subdomains aren’t separately verifiable; verifying the parent unlocks them. - IDN / Punycode: hostnames are normalized to lowercase ASCII Punycode before comparison. We currently reject
xn--domains (mixed-script protection); contact support if you operate from one. - Subdomain takeover: if you verify
acme.coand later letforms.acme.coCNAME-dangle, an attacker who claims that CNAME can use your verified-domain authorization. To narrow that exposure, register explicit patterns on the Allowed redirect URIs card. - Public suffixes: bare public suffixes like
co.ukare rejected. We use a hand-curated list of common multi-label suffixes (co.uk,com.au,co.jp, etc.); the registrable domain is the label above the suffix. - Cross-org ownership: only one organization can be the active owner of a domain at any time. A second organization that completes a DNS challenge takes over (see Verifying a domain another organization owns); the previous owner is notified by email and can re-verify to win it back.
Errors
Common error codes when working with the domain endpoints:| Code | Status | Meaning |
|---|---|---|
APEX_INVALID | 400 | The supplied value isn’t a valid registrable domain — it’s a bare public suffix, an IDN, or otherwise malformed. |
APEX_TAKEOVER_REQUIRED | 409 | Another organization holds an active verification for this domain. Re-submit POST /domains/challenges/dns/verify with acknowledge_takeover: true to transfer ownership. The error details.conflictingOrganizationName carries the previous owner’s name. |
CHALLENGE_NOT_FOUND | 404 | The challenge ID is unknown or has been consumed. |
CHALLENGE_EXPIRED | 400 | More than 7 days have passed; start a new challenge. |
DNS_NOT_PROPAGATED | 409 | We didn’t see the TXT record at the domain. Wait a few minutes and try again. |
DNS_LOOKUP_FAILED | 503 | Both upstream DNS resolvers were unreachable. Try again shortly. |
DOMAIN_NOT_FOUND | 404 | The verified-domain (or redirect-URI) row referenced doesn’t belong to your organization. |
FORBIDDEN | 403 | The caller isn’t an owner of the organization. |
REDIRECT_URL_DOMAIN_NOT_VERIFIED | 400 | A session was created with a redirect_url whose host isn’t on a verified domain. |
REDIRECT_URL_PATTERN_NOT_REGISTERED | 400 | The redirect URL host is on a verified domain but doesn’t match any registered pattern for that domain. |