- Status: version 0.1 of Daawid's open specification.
- Licence: this text is CC BY 4.0.
- Related: the pointer record and its carriers are in identifiers.md §4; the wording for consumers is in data-contract.md §2.3.
- Names:
daawid.examplestands for daawid.com. Every name in the examples is fictional.
1. What "verified" means (normative)
verified (level domain) means exactly this: the organization that maintains the entry has shown that it controls the listed domain(s). It did so by publishing a Daawid pointer bound to that organization, and Daawid re-checked the pointer at lastCheckedAt.
Level contact means exactly this: the account that publishes the entry confirmed an email address. Nothing about who runs the entry is checked. It lets anyone publish without a domain; trust, ranking weight and actions grow with the higher levels.
Neither level means that Daawid has checked:
- the declared facts, prices, quality, licences, insurance or solvency;
- that the business is the legal entity it names. That is level
business, reserved for v0.2 (§8).
Wording for consumers:
- Required pattern: "Information provided by Holzwerk Krause. Daawid confirmed on 2026-10-28 that this business controls holzwerk-krause.example."
- Required pattern at
contact: "Information provided by the entry's owner. On 2026-10-30, Daawid confirmed an email address for this entry, not who runs it." - Prohibited: "Daawid-certified", "trusted", "approved", "recommended".
Why domain control. A domain is the identity customers already recognize, and it's the anchor that search engines and AI systems already use for a business's "official website". Proving control of the domain ties the entry to whoever controls that official site. This is also the established method: Google, Meta, Microsoft, GitHub, the AT Protocol and the IETF's draft all use it. People verify a personal domain the same way.
2. Levels
Levels form a ladder, lowest first:
| Level | Meaning | Unlocks | v0.1 |
|---|---|---|---|
none |
Unclaimed, or every check has lapsed | Public-record fields only | yes |
contact |
The owner account confirmed an email address. Nothing about who runs the entry is checked. | Publishing all owner fields; inquiry actions within the limits in §2.1 | yes |
domain |
Control of at least one primary domain is proven and current |
All owner fields, inquiry actions, full ranking weight | yes |
business |
Domain level, plus the legal entity confirmed against the register, an Impressum match, and either a letter code to the registered address or a check of a signatory's identity | Transactional actions (orders, payments) and trader traceability (§8) | reserved |
identity |
For person entries: the person's name confirmed with an eID or an ID-document check | A stronger label; required before a person takes transactional actions | reserved |
How entry status relates to verification.level:
status |
verification.level |
|---|---|
unclaimed |
none |
published |
contact |
verified |
domain, business or identity |
lapsed |
none |
suspended |
independent of level |
When domain verification lapses, an entry whose owner account still has a confirmed email address becomes published at level contact instead of lapsed (§5).
A claim that is in progress is private. The public keeps seeing the previous status.
2.1 Abuse controls for open publishing
Open publishing attracts fakes. The controls in v0.1:
- Rate of creation: one confirmed email address publishes at most 3 entries, unless Daawid's staff raise the number for an account, such as an agency's that wrote to Daawid, and addresses from disposable-email domains are refused, by the open-source disposable-email-domains list (CC0). Existing accounts aren't touched.
- Bot check at sign-up: the sign-in service's own, with no script on Daawid's public pages. Daawid's own forms (requests, reports) ask for an emailed code instead.
- Review queue: a confirmed report opens a case in the review queue, which Daawid's staff see in the console, and Daawid emails them that it did; so do a check whose resolvers keep disagreeing (§7) and two organizations proving one website (§6). The reviewer closes a case with no action, or suspends the entry, with a reason either way. A suspended entry's actions are off, its waiting requests close, and its owners' publishes and changes wait until the suspension is lifted.
- No SEO payoff for spam: below
domain, HTML pages arenoindexfor their first 30 days and while an abuse report is open, and outbound links carryrel="ugc nofollow"(data-contract §2.2). Markdown, JSON and MCP serve immediately. - Actions below
domain: at most 20 requests sent and 100 started a day per entry, 3 waiting per requester address and entry, and the code emails limited per address and per browser; the tools themselves have no limit per IP, because AI apps in the cloud call from their own servers. The confirmation step shows thecontactwording before the user sends any personal data (data-contract §7.6). - Ranking: verification level is a published ranking signal, applied the same way to every entry. There is no paid ranking.
- Notice and action: every entry page links to
/{slug}/report(identifiers.md §3.1), where the reporter says what's wrong, explains it, and gives their name and email address with a statement of good faith (DSA Art. 16). Daawid emails a code first, with the limits of request codes, and an address has at most 3 open reports. The reporter gets an email confirming the report and one with the decision. A suspended entry's owners get the reason by email (Art. 17) and appeal by replying. A report is kept for a year after its decision, and one whose code was never typed in for a day. - Impersonation: names aren't unique and confer no exclusivity. Labels show what was checked; disputes follow §6.
3. Claim flow, step by step
Account. The owner signs up with an email address, confirmed with a one-time code or a link. There is no mobile number in v0.1. The minimum age is 18. An owner organization (
org_…) is created; for an individual it is a one-person organization. Verification and tokens are bound to this organization, not to a person, so staff turnover doesn't break them.Pick or create the entry.
- Search by name or domain. Claiming an existing entry opens a private claim (
clm_…). - Or create a new entry and choose its kind, person or organization. People, sole traders and partnerships of natural persons always come in this way, because they never have unclaimed entries (entry-schema §3). Creation happens in the owner console, with a category template and an optional import (data-contract §7.4).
- Search by name or domain. Claiming an existing entry opens a private claim (
Legal data, if the owner gives it. The operator block is optional. The console offers it, and reminds owners in Germany of what § 5 DDG asks: electronic contact, the register and representatives where they apply, and for sole traders a legal name that contains their full name. A publish never waits for it.
New entries can now be published at level
contact, before any domain is added; steps 4–9 can follow at any time. Claiming an existing unclaimed entry never publishes atcontact. It needs the binding check (step 5) and a verified domain, so nobody can take over a company's entry with only an email address.Add a domain. Daawid then:
- Normalizes the host: lowercase, UTS #46 to A-label, and strips any scheme, path or port.
- Rejects public suffixes, and hosts under private-section PSL suffixes such as site-builder subdomains.
- Checks for conflicts (§6).
Only the entry's owners add or remove websites, which are kept outside the draft that editors save, and every entry Daawid composes takes its
domainsandverificationfrom them. A leadingwww.goes when the rest is a registrable domain, because the record there coverswwwas well (identifiers.md §4.3). Each website is aprimarydomain; the console offers no roles until owners ask. IP addresses are refused too. A website is published in the entry once it is verified, and stays while its grace period runs (§5).Binding check. This applies only when claiming an existing entry, whose legal identity is already known from the register. Proving control of some domain says nothing about being that GmbH. The claim continues automatically if either:
- the domain is already linked to the entry through provenance
business_website, meaning Daawid found this entry's Impressum on that domain; or - the domain's Impressum, fetched during the check, contains the entry's register court and number, or its legal name and postal code.
Otherwise the claim is held for manual review. The reviewer may require a letter code sent to the registered address.
Where the law asks for a legal notice on a website, as Germany's does (§5 DDG), it is a cheap, machine-checkable link between a domain and a legal entity.
- the domain is already linked to the entry through provenance
Token issued.
tis bound to (organization, entry, host). Daawid shows the record in all three forms: DNS TXT, meta tag and well-known file (identifiers.md §4.2). It reads the domain's NS records to name the DNS provider in its instructions. One-click setup through Domain Connect waits: each DNS provider has to onboard Daawid with a template of its own. The token is 26 random characters (130 bits), kept with its binding: a website removed and added again keeps it.Owner publishes the pointer.
Check. The claimant clicks "check now". Daawid also retries automatically at 1, 5, 15 and 60 minutes, then hourly for 72 hours. The short retries come from the console while it is open, and Daawid's hourly round takes over; after 72 hours, Daawid waits for the next "check now".
Success:
- The domain becomes
verified. - Entry
statusbecomesverifiedandverification.levelbecomesdomain. - Owner-tier fields unlock.
- The first publish re-renders all artifacts.
- Everyone involved is notified, including any previous owner organization.
- The domain becomes
4. Checker specification
DNS TXT (preferred)
- Query: TXT records at
_daawid.{host}, through at least 2 independent DNS-over-HTTPS resolvers that validate DNSSEC: Cloudflare's, Google's and Quad9's, over RFC 8484. Two are asked first, and the third when they disagree or one doesn't answer. - Accept the answer when either:
- it is DNSSEC-authenticated, or
- at least 2 resolvers return identical record sets. The IETF's draft recommends "matching responses from multiple DNS resolvers" when DNSSEC is absent.
- Fail closed on DNSSEC
bogus. - CNAMEs: follow up to 3 hops. This allows delegation, for example an agency managing many clients.
- Long records: concatenate multi-string TXT records.
- Match: check every record. The check passes if any record parses with
v=1,eequal to the entry ID, andtequal to the token issued for this (organization, entry, host).
HTML meta tag
GET https://{host}/: HTTPS on port 443 only, valid TLS.- User agent
DaawidVerifier/1.0 (+https://daawid.example/docs/verifier). Its requests leave from a shared network, so Daawid has no addresses of its own to publish:/docs/verifiernames the user agent and says so, and DNS needs no allowlist at all. - Hosts under Daawid's own domains verify by DNS only.
- Limits: 10 s timeout, 1 MB maximum.
- Redirects: at most 5, and only within the same registrable domain, and never to a Daawid-controlled host.
- Parse the server-rendered
<head>only. JavaScript is never executed. - Look for
meta[name="daawid"]. Several tags are allowed.
Well-known file
GET https://{host}/.well-known/daawid.text/plain, at most 1 KB. A type that names no format (application/octet-stream, which many static hosts send for files without an extension) counts too; an HTML page never does.- Redirects only to the same host, and from the registrable domain to its
www, which the record covers as well. - Otherwise the same rules as the HTML method.
Order. DNS, then the file, then the meta tag; the first that passes counts, and Daawid records which one it was.
5. Continuous verification
The record stays in place permanently (identifiers.md §4.3), so re-checking is cheap.
Schedule:
- Daily for the first 7 days after success, then weekly, with jitter.
- A failed check is tried again 12 hours later, so three failures in a row span at least 24 hours.
- Each round checks a bounded number of websites, the ones due longest first.
State machine for each domain:
verified ──(scheduled check fails 3× over 24 h)──▶ grace ──(14 days, still failing)──▶ lapsed
▲ │ │
└──────────────(any successful check)──────────────┴──────────────────────────────────┘
grace:- The entry stays
verifiedand actions keep working. - Owners are notified on day 0, 3 and 10, with what Daawid found and how to fix it.
- The domain is checked daily.
- Consumers see the domain's status as
grace.
- The entry stays
lapsedfor a domain: that domain no longer counts. If noprimarydomain is stillverifiedorgrace, there are two cases:- The owner account still has a confirmed email address: the entry becomes
publishedat levelcontact. Actions continue within the limits of §2.1, and consumers see thecontactwording. - Otherwise:
- Entry
statusbecomeslapsedand the level becomesnone. - Actions are disabled immediately.
- Owner content stays visible for 30 days under the lapsed framing line (data-contract §3.3).
- After that, owner content is withdrawn from all projections. The entry then shows public-record fields only, kept privately for 12 months, then deleted unless re-verified.
- Entry
- The lapsed domain leaves the published entry, and is checked again when an owner presses "check now". Every entry in v0.1 has an owner with a confirmed email address, so the second case can't happen until accounts can close or entries can be claimed, and isn't built until then.
- The owner account still has a confirmed email address: the entry becomes
- Re-verification restores everything at once. The token stays the same if the binding is unchanged.
- What goes out: a change of state goes out at once as the entry's next revision. A passing check that changes nothing goes out only once the published
lastCheckedAtis more than 30 days old, so the date on the pages is at most about five weeks old.verifiedAtis when the current run of passing checks began;lastCheckedAtis the last check that found the record. Owners get an email when a domain is verified, when its grace period starts, when it is back, and when it lapses.
Content confirmation is separate from verification. Owners confirm "still accurate" at least every 12 months (lastConfirmedAt). Capacity expires on its own after at most 30 days. Consumers see stale content as stale; it doesn't change the verification status.
6. Ownership, roles, disputes
Roles inside an owner organization:
| Role | Can do |
|---|---|
owner |
Domains, members, transfers, action delivery destinations |
editor |
Content |
viewer |
Read only |
Every verification event and every ownership-relevant change is written to the audit log. In this version owners sign in with an emailed code; a passkey or a second step comes later.
Sensitive operations:
- adding or removing a domain
- enabling an action
- changing an action's
fulfillmentdestination - transferring the entry
- changing the slug
These need the owner role, and all owners get an email.
A new address for requests starts 24 hours after it is confirmed. That is the window for noticing a compromised account trying to divert leads. The owners' email says when, and has a link that stops the change without signing in, and until then requests keep going where they went. Another address must first confirm a link Daawid sends it. Switching requests on to the address the owner signs in with starts at once, because nothing is diverted. A fresh domain check wouldn't prove who is acting, since the record stays in place by design. Transfers and slug changes of published entries aren't built yet, and these rules apply when they are, with the token rotated on a transfer.
Conflicts:
- Another organization proves control of a host already verified for organization A:
- If A's record is gone (A is in grace or lapsed): ownership transfers after a 7-day notice to A's owners. A can block it by re-proving control.
- If both records are present: whoever controls DNS allowed both, so the case goes to manual review, and neither side can make ownership changes meanwhile.
- Meanwhile the newer claim isn't verified, and the case is in the review queue (§2.1). One organization may verify a host for several of its entries, such as a holding company's brands: each record is read on its own.
- The newer claim is held, and checked daily with the first organization's record, which is checked again first. With that record gone, A's owners get the notice, and the host moves once the 7 days are over, its record still gone: A's website no longer counts, as after a lapse. With both records there, the reviewer decides whose the host is: it stays with A, and the newer claim is taken off its entry, or it moves, and A's entry loses it. Both sides' owners get the decision with its reason, and can reply to appeal. Neither side's emails name the other organization: a claim in progress is private.
- Domain sold or expired: the pointer disappears, so the entry lapses. That's the correct outcome. The pointer checks are the mechanism; a registry's public expiry data, where there is any, could trigger an early re-check.
- Business sold. Organization A transfers the entry to organization B:
- The token is rotated.
- B must publish its own record within 14 days (treated as grace), or the entry lapses.
- A's old record becomes inert.
- Legal disputes (trademark or name rights, impersonation) follow a manual process. They can lead to suspension and slug transfer (identifiers.md §2).
7. Failure modes
| Failure | Detection | Handling |
|---|---|---|
| Record not visible yet (propagation, negative caching) | NXDOMAIN or no match | Automatic retries (§3, step 8). Show the SOA minimum TTL as the expected wait. |
Hoster appended the zone: _daawid.acme.de.acme.de |
Probe the doubled name | Show the exact fix. Don't accept it. |
Record placed at the apex instead of _daawid |
Probe apex TXT | Show the fix. Don't accept it; the draft calls apex records "unfortunate". |
| Several Daawid records, tokens for different entries | Parse all of them | Evaluate each independently (identifiers.md §4.3). |
| Old and new token both present for the same entry | Parse all of them | Use the current token. Prompt removal of the old one. |
| TXT value split into several strings | Standard parsing | Concatenate. |
CNAME at _daawid |
Resolver answer | Follow up to 3 hops (agency delegation). |
| DNSSEC bogus | Validating resolvers return SERVFAIL | Fail closed. Tell the owner to fix DNSSEC with their hoster. |
| Resolvers disagree (no DNSSEC) | Answers differ | Retry. If it persists, flag a possible hijack and check by hand, in the review queue. |
| Head built by JavaScript (site builders, SPAs) | No meta tag in the raw HTML | Suggest the DNS or file method. We never run JavaScript. |
| Bot protection blocks the verifier (403 or a challenge page) | Status code or challenge markers | Suggest DNS. Publish the verifier's user agent for allowlisting. |
| Redirect to another registrable domain | Host of the Location header |
Not followed. Fail with an explanation. |
| Domain redirects to Daawid, because the website was replaced | Target is a Daawid host | Never accepted, since that would let an entry verify itself. DNS is required. |
Platform subdomain (e.g. name.sitebuilder.example) |
PSL private section | Can't be verified in v0.1. The owner publishes at level contact instead. |
| IDN or mixed case | UTS #46 | Store A-labels, display U-labels. |
| Token copied to another domain or account | Binding check | Has no effect: the token is bound to (organization, entry, host). |
| Domain verified, but it's the wrong company's domain | Binding check (§3, step 5) | Manual review and a letter code. Comes with claims of existing entries: until then every entry is made by its owner. |
| Account takeover | Owner notifications; 24-hour delay on fulfillment changes |
A new address for requests starts 24 hours after it is confirmed, every owner gets an email with a link that stops it without signing in, and the audit log keeps every step. Passkeys and a second step come later. |
| Subdomain takeover on the business's host | Out of our control | Affects only the HTML and file methods, which is why DNS is the default. |
| Entry deleted, record still published | Entry returns 410 | Harmless. Checking stops. |
8. Business verification (reserved for v0.2)
Purpose. The business level lets Daawid say "this entry belongs to legal entity X (register Y), which controls domain Z".
When it's needed:
- before transactional actions such as orders and payments;
- for trader traceability, if Daawid becomes a platform where consumers conclude contracts with traders. That is the DSA Art. 30 duty for marketplaces.
Inputs:
- Register match. Legal name, form, seat, register court and number, and representatives must match the country's public register, through a permitted channel.
- Impressum match on the verified domain, where a website exists.
- One of:
- a letter with a one-time code sent to the registered address (the analogue of the Google Business Profile postcard); or
- an identity check of a registered representative (eID or video ident).
Natural persons with no register entry would verify with a Gewerbeanmeldung or Handwerkskarte document plus a manual check. That comes after v0.2.
9. The IETF's draft
draft-ietf-dnsop-domain-verification-techniques (an Internet-Draft, intended status BCP) covers DNS. How this design follows it:
| The draft's recommendation | This design |
|---|---|
| Underscore-prefixed application label | _daawid |
| TXT records | TXT |
| Token first in the key-value list | t= first |
| Token must match the one issued to the user | Bound to the organization |
| Persistence only when bound to an account | Persistent and bound |
| Document the scope | identifiers.md §4.3 |
| State how long the token is valid | Valid while the binding stands |
| Use multiple resolvers without DNSSEC; validate DNSSEC | Both |
| Avoid apex records | Apex not accepted |
| Don't verify public suffixes | Refused |
| Short TTL | 300–3600 s suggested |
Email and HTTP methods are out of the draft's scope, so the HTML and file carriers follow the conventions of common domain-verification flows.