DelegusDocsv0.3 rc1

Docs/Verify your domain

Getting started

Verify your domain

Before Delegus trusts anything that carries your company's name, you show that you control your company's domain. You do it once, by publishing a short code that Delegus gives you, either in your DNS or as a small file on your website. Delegus then checks it again every day.

This page describes the v0.3 release candidate, which is not yet frozen, so details can still change.

Who needs this#

You areWhat needs a verified domainWithout it
A seller or service checking agents on your own identity (a relying party on your own did:web, such as did:web:computeco.example)Every /verify callHTTP 403 RP_UNVERIFIED: no decision, no receipt
A company whose agents act, signing Grants as your own did:web (a Principal, such as did:web:acme.example)Every decision about your agents' GrantsA signed DENY with reason ISSUER_UNVERIFIED
Any organization that wants production checks or a paid planTurning production onProduction stays off; the sandbox keeps working

You do not need this for the sandbox, or for identities Delegus hosts for you (did:web:delegus.ai:rp:<slug> and did:web:delegus.ai:org:<slug>). Those work in the sandbox but do not count as a verified company domain.

A few terms used below. A claim is your organization's request to own a domain in Delegus. A relying party is the service that receives an agent's request and asks Delegus whether to accept it. A Principal is the company that gave the agent its authority.

Before you start#

Which domains your email can claim: the domain of your email, or any domain under it, but never a domain above it or beside it.

Signed in asCan claimCannot claim
ana@acme.exampleacme.example, shop.acme.example, a.b.acme.examplecomputeco.example
ana@shop.acme.exampleshop.acme.exampleacme.example (that is above it)
ana@gmail.comnothingany domain

The claim covers that one domain, exactly. A claim on computeco.example does not verify did:web:api.computeco.example; claim api.computeco.example for that.

1. Start a claim#

In the console, open Identities, go to Your company domains, enter the domain under Domain to claim, confirm that you control it (this records your acceptance of the acceptable-use terms), and choose Claim this domain.

The console makes this call for you. It is listed here so you know what is recorded; your own API keys cannot start a claim.

http
POST /domain-claims
authorization: Bearer <console provision key>
content-type: application/json

{
  "domain": "acme.example",
  "org_id": "<your org id>",
  "claimant_email": "ana@acme.example",
  "terms": {
    "accepted_by": "ana@acme.example",
    "accepted_at": "2026-09-25T16:00:00Z",
    "version": "1.1"
  }
}

terms must be exactly these three fields: accepted_by (who accepted), accepted_at (when, as a date and time) and version (the version of the terms). The answer is HTTP 201 with the claim in state pending and the values to publish:

json
{
  "claim_id": "dcl_...",
  "domain": "acme.example",
  "state": "pending",
  "proof": {
    "token": "<token>",
    "dns_txt_name": "_delegus.acme.example",
    "dns_txt_value": "delegus-verify=<token>",
    "well_known_url": "https://acme.example/.well-known/delegus.json",
    "well_known_body": { "tokens": ["<token>"] }
  },
  "expires_at": "...",
  "next_check_at": "...",
  "terms_url": "https://delegus.ai/terms#acceptable-use"
}

That is a trimmed view. A pending claim reserves nothing: it does not stop anyone else from claiming the same domain (see First verified wins).

2. Publish the proof#

Publish one of the two below. You need only one.

Add the TXT record#

Add a DNS TXT record at your DNS provider:

FieldValue
TypeTXT
Name_delegus.acme.example (many providers want only _delegus; they add the domain)
Valuedelegus-verify=<token>

Use the exact value the console shows. Other TXT records at the same name are fine; Delegus looks for one that matches.

CloudflareGoDaddyNamecheapSquarespace DomainsAWS Route 53Google Cloud DNSVercelPorkbunIONOSAzure DNSHoverWixOther provider

Cloudflare#

Host / Name field. Type only the part before your domain: _delegus. Cloudflare's docs say to use only the subdomain part for the record Name, with @ for the domain itself.

  1. Sign in to the Cloudflare dashboard and open your domain.
  2. Go to the "DNS Records" page.
  3. Select "Add record".
  4. For "Type", choose "TXT".
  5. In "Name", type _delegus.
  6. In the content field, paste delegus-verify=<token>.
  7. Leave "TTL" as it is.
  8. Select "Save".

Value. Cloudflare says: "if you save your TXT content without any quotes, Cloudflare will automatically add double quotes." Paste the value without quotes.

TTL. Leave the default.

How long. "By default, any changes or additions you make to your Cloudflare zone file will take effect globally within 5 minutes, usually much less."

From Cloudflare’s own help page, developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

GoDaddy#

Host / Name field. Type only the part before your domain: _delegus. GoDaddy's Name field is "the hostname or prefix of the record, without the domain name"; @ means the domain itself.

  1. Sign in to your GoDaddy "Domain Portfolio".
  2. Select your domain to open its "Domain Settings" page.
  3. Select "DNS" to see your DNS records.
  4. Select "Add New Record", then choose "TXT" from the "Type" menu.
  5. In "Name", type _delegus.
  6. In "Value", paste delegus-verify=<token>.
  7. Leave "TTL" at the default.
  8. Select "Save".

Value. GoDaddy allows at most 1024 characters in Value, ASCII only.

TTL. The default is 1 hour; leave it.

How long. "Most DNS updates take effect within an hour but could take up to 48 hours to update globally."

From GoDaddy’s own help page, www.godaddy.com/help/add-a-txt-record-19232, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Namecheap#

Host / Name field. Type only the part before your domain: _delegus. Namecheap says "the domain name itself should not be included in the Host field"; @ means the domain itself.

  1. Sign in to your Namecheap account.
  2. Choose "Domain List" on the left, then click "Manage" next to your domain.
  3. Open the "Advanced DNS" tab.
  4. Click "Add new record".
  5. For "Type", choose "TXT Record".
  6. In "Host", type _delegus.
  7. In "Value", paste delegus-verify=<token>.
  8. Click "Save all changes".

TTL. Leave the default.

How long. "Normally, it takes 30 minutes for newly created host records to take effect."

From Namecheap’s own help page, www.namecheap.com/support/knowledgebase/article.aspx/317/2237/how-do-i-add-txtspfdkimdmarc-records-for-my-domain/, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Squarespace Domains (formerly Google Domains)#

If your nameservers look like ns-cloud-*.googledomains.com, the domain may be managed in either Google Cloud DNS or Squarespace Domains, so check which account shows the domain.

Host / Name field. Type only the part before your domain: _delegus. Squarespace says it "automatically adds your domain to the Name field", so typing the full name would repeat the domain; @ means the domain itself.

  1. Open your domains dashboard at account.squarespace.com/domains and select your domain.
  2. Click "DNS", then click "DNS Settings".
  3. Scroll down to "Custom Records".
  4. Click "Add record".
  5. If asked, enter your password or confirm with two-factor authentication, then click "Continue".
  6. In the "Type" menu, select "TXT".
  7. In "Name", type _delegus.
  8. In "Text", paste delegus-verify=<token>.
  9. Click "Save".

TTL. Custom records default to a 4-hour TTL; leave it.

How long. "it can take 24 to 48 hours for the change to your records to update."

From Squarespace Domains (formerly Google Domains)’s own help page, support.squarespace.com/hc/en-us/articles/31120980444429-Adding-TXT-records, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

AWS Route 53#

Host / Name field. Either form works: _delegus. AWS's page for this form does not state which form it expects: it says to enter "the name of the domain or subdomain" and that "The default value is the name of the hosted zone." Leave it empty for the domain itself, and do not type @.

  1. Sign in to the AWS Management Console and open the Route 53 console.
  2. In the navigation pane, choose "Hosted zones".
  3. Choose the name of the hosted zone for your domain.
  4. Choose "Create record".
  5. For "Routing policy", choose "Simple routing" if asked.
  6. In "Record name", enter _delegus. If your provider shows your domain after the field, or the saved record reads _delegus.<domain>.<domain>, edit it to just _delegus.
  7. For "Record type", choose "TXT".
  8. In "Value", type "delegus-verify=<token>" including the double quotes.
  9. Set "TTL (seconds)" to 300.
  10. Choose "Create records".

Value. Route 53 says: "Enclose text in quotation marks", for example "delegus-verify=<token>".

TTL. AWS suggests a shorter value such as 300 seconds when setting up a new record.

How long. "Changes generally propagate to all Route 53 name servers within 60 seconds."

From AWS Route 53’s own help page, docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Google Cloud DNS#

If your nameservers look like ns-cloud-*.googledomains.com, the domain may be managed in either Google Cloud DNS or Squarespace Domains, so check which account shows the domain.

Host / Name field. Type only the part before your domain: _delegus. Google says to "enter the subdomain of the DNS zone" in DNS name ("the trailing dot is automatically added"); leave it blank for the domain itself.

  1. In the Google Cloud console, go to the "Cloud DNS zones" page.
  2. Click the name of the managed zone for your domain.
  3. On the "Zone details" page, click "Add standard".
  4. On the "Create record set" page, in "DNS name", type _delegus.
  5. For "Resource record type", select "TXT".
  6. Enter a number in "TTL" (300 is a good choice).
  7. In the value field, enter delegus-verify=<token>.
  8. Click "Create".

TTL. Google's page does not name a value; 300 seconds is a reasonable choice.

How long. Google says your authoritative name server should pick up the change "within 120 seconds."

From Google Cloud DNS’s own help page, docs.cloud.google.com/dns/docs/records, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Vercel#

Host / Name field. Type only the part before your domain: _delegus. Vercel's Name field is "the prefix or location of the record"; its docs say to enter only the prefix, not the full name, and to leave it blank for the domain itself.

  1. On your team's dashboard, open "Domains" in the sidebar.
  2. Click your domain to open its settings page.
  3. Open the DNS record form (the docs call the button "Enable Vercel DNS").
  4. In "Name", type _delegus.
  5. For "Type", choose "TXT".
  6. In "Value", paste delegus-verify=<token>.
  7. Leave "TTL" at the default.
  8. Click "Add".

TTL. The default is 60 seconds; leave it.

How long. "Once a DNS record has been added, it can take up to 24 hours to the DNS records to fully update and any local caches to be cleared."

From Vercel’s own help page, vercel.com/docs/domains/managing-dns-records, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Porkbun#

Host / Name field. Either form works: _delegus. Porkbun's page does not state which form it expects or whether it adds your domain; it says to leave Host blank for the domain itself and to enter the subdomain name otherwise.

  1. Sign in to Porkbun and go to "Domain Management".
  2. Find your domain and click "DNS" under it (or click "Details", then the edit icon under "DNS RECORDS").
  3. Click "Add Record".
  4. For "Type", choose "TXT".
  5. In "Host", enter _delegus. If your provider shows your domain after the field, or the saved record reads _delegus.<domain>.<domain>, edit it to just _delegus.
  6. In "Answer", paste delegus-verify=<token>.
  7. Leave "TTL" at the default.
  8. Click "Add".

TTL. Porkbun: "You can usually leave this field set to the default value unless otherwise instructed."

From Porkbun’s own help page, kb.porkbun.com/article/231-how-to-add-dns-records-on-porkbun, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

IONOS#

Host / Name field. Type only the part before your domain: _delegus. IONOS asks for just the host part, such as www, or @ for the domain itself.

  1. Sign in to IONOS.
  2. For your domain, click the gear symbol under "Actions" and select "DNS".
  3. Click "Add Record" and select "TXT" under "Type".
  4. In "Host name", type _delegus.
  5. In "Value", paste delegus-verify=<token>.
  6. Leave "TTL" at the default.
  7. Click "Save".

TTL. Optional; the default is fine.

How long. "Your changes are effective at IONOS immediately. However, it can take up to 1 hour for the change to take effect externally."

From IONOS’s own help page, www.ionos.com/help/domains/configuring-txt-and-srv-records/managing-txt-records/, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Azure DNS#

Host / Name field. Type only the part before your domain: _delegus. Azure's Name field takes the host name inside the zone (its example is www for www.contoso.xyz); @ is the zone apex.

  1. Sign in to the Azure portal.
  2. In the search box at the top of the portal, enter "DNS zones" and select it, then select your DNS zone.
  3. Select "+ Record sets" at the top of the zone's "Overview" page, then select "+ Add".
  4. On the "Add record set" page, in "Name", type _delegus.
  5. For "Type", select "TXT".
  6. Set "TTL" to 600 and "TTL unit" to "Seconds".
  7. In "Value", paste delegus-verify=<token>.
  8. Select "Add".

TTL. Microsoft's own TXT example uses 600 seconds.

How long. "New or updated DNS zones and DNS records appear in the Azure DNS name servers within 60 seconds."

From Azure DNS’s own help page, learn.microsoft.com/en-us/azure/dns/dns-web-sites-custom-domain, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Hover#

Host / Name field. Type only the part before your domain: _delegus. Hover asks for the subdomain part, or @ for the domain itself; if a service tells you to enter your full domain, Hover says to use @ instead.

  1. Sign in to your Hover control panel.
  2. Go to your domain's "Overview" page and click the "DNS" section.
  3. Click "Add a record".
  4. Select "TXT" as the record type.
  5. In "Hostname", type _delegus.
  6. In "Content", paste delegus-verify=<token>.
  7. Save the record.

TTL. Leave the default.

How long. "DNS changes can take up to 24–48 hours to fully propagate across the internet."

From Hover’s own help page, support.hover.com/support/solutions/articles/201000064728-managing-dns-records, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Wix#

Host / Name field. Either form works: _delegus. Wix's page does not state which form it expects or whether it adds your domain; it says only to leave Host Name blank where you were told to use @.

  1. Go to "Domains" in your Wix account.
  2. Click the "Domain Actions" icon next to your domain.
  3. Select "Manage DNS Records".
  4. In the "TXT (Text)" section, click "+ Add Record".
  5. In "Host Name", enter _delegus. If your provider shows your domain after the field, or the saved record reads _delegus.<domain>.<domain>, edit it to just _delegus.
  6. In "Value", paste delegus-verify=<token>.
  7. Click "Save".

TTL. Wix: "We recommend leaving the TTL setting for your DNS records at the default value."

From Wix’s own help page, support.wix.com/en/article/adding-or-updating-txt-records-in-your-wix-account, checked 2026-09-25. Providers change their screens; if a step doesn’t match, follow their page.

Other provider#

Host / Name field. Either form works: _delegus. Most providers add your domain for you, so the short form _delegus is the usual answer; existing records in the same zone show which form yours expects.

  1. Find out who runs your domain's DNS: run dig +short NS <domain>, or look it up with an online DNS lookup. The names returned belong to the company that hosts your DNS.
  2. Sign in there and open the DNS settings (sometimes called the zone, DNS records, or host records) for your domain.
  3. Look at an existing record first. If it shows a short name like "www" or "@", the Host field wants the short form: type _delegus. If existing records show the full name, such as "www.<domain>", type _delegus.<domain>.
  4. Add a new record with type TXT, the host from the step above, and the value delegus-verify=<token>.
  5. Leave TTL at the default, or pick a short value such as 300 seconds, and save.
  6. Check it: run dig +short TXT _delegus.<domain> or use an online TXT lookup. You should see "delegus-verify=<token>".
  7. If the lookup shows nothing, check whether the record was saved as _delegus.<domain>.<domain>. If so, edit it and type only _delegus.

Value. Enter the value exactly as shown in the Delegus console. If your provider shows TXT values in quotes, follow its format.

TTL. The default is fine.

No DNS access: the file route#

Host / Name field. Type the full name, including your domain: https://<domain>/.well-known/delegus.json. The file must be served on the domain itself over HTTPS, not on a subdomain or a different host.

  1. Create a file named delegus.json.
  2. Put exactly this in it: {"tokens": ["<token>"]}. To verify more than once, list several tokens in the same array.
  3. Keep the file at 4096 bytes or less.
  4. Publish it at https://<domain>/.well-known/delegus.json so that it returns HTTP 200.
  5. Open that address in a browser and confirm you see the file, not a redirect or an error page.
  6. Return to the Delegus console and run the check.

Value. The body is JSON: {"tokens": ["<token>"]}, at most 4096 bytes.

Or publish the file#

Serve this file at https://acme.example/.well-known/delegus.json:

json
{ "tokens": ["<token>"] }

3. Check#

Choose Check my domain in the console. Delegus also checks pending claims on its own, about once an hour, so you can simply wait.

With an organization key you can read your claims, and with an org:admin key run the same check, yourself:

bash
# Check one claim now (org:admin key)
curl -s -X POST https://api.delegus.ai/domain-claims/dcl_.../verify \
  -H "authorization: Bearer $DELEGUS_ORG_ADMIN_KEY"

# List your organization's claims (org:read or org:admin key)
curl -s https://api.delegus.ai/domain-claims \
  -H "authorization: Bearer $DELEGUS_ORG_KEY"

GET /domain-claims/{id} returns one claim. When the proof is found, state becomes verified and method says how (dns_txt or well_known). If it is not found yet, the claim stays pending and failure says why, for example no proof found.

/domain-claims is available on the production API (api.delegus.ai) and on the development environment.

What happens after#

StateMeaning
pendingWaiting for the proof. Expires 7 days after you start the claim.
verifiedYour organization owns the domain. Delegus re-checks it every 24 hours.
lapsedRe-checks have failed for 72 hours. Checks that need the domain are refused until it passes again.
expiredThe pending claim ran out. Start a new one.
closedEnded; closed_reason says why (below).

First verified wins#

Several organizations may hold pending claims on the same domain. The first one whose proof is found owns it. At that moment every other pending claim on that domain is closed with closed_reason: "domain_verified_by_another_org". Only one organization can own a domain at a time, and while it owns it (verified or lapsed), a new claim by another organization is refused with CLAIM_DOMAIN_VERIFIED.

Delegus staff can move a claim to another organization or revoke it, with a recorded reason, for example after a misuse report. If you believe someone else holds your domain, write to hello@delegus.ai.

Using the verified domain#

Relying party on your own domain. Register it after you have started the claim; it works once the claim is verified.

bash
curl -s -X POST https://api.delegus.ai/relying-parties \
  -H "authorization: Bearer $DELEGUS_ORG_ADMIN_KEY" \
  -H "content-type: application/json" \
  -d '{"kind":"hosted","did":"did:web:computeco.example","name":"ComputeCo"}'

Without an open claim (pending, verified or lapsed) on computeco.example for your organization, this returns HTTP 403 CLAIM_REQUIRED.

Principal on your own domain. POST /principals with {"kind":"hosted","did":"did:web:acme.example"} has the same rule and the same CLAIM_REQUIRED refusal. Grants signed as did:web:acme.example pass the domain check (T2) only while the claim is verified, including the 72-hour window after a failed re-check.

A hosted Principal passes the domain check (T2) if its own verification token verified (the v0.2 path) or, for a relying party on delegus-base-v3, if your organization holds a verified claim on that domain. Registering a hosted Principal needs the verified claim in any case. So claim the domain once: under v0.3 that covers every hosted Principal and relying party on it. The Principal's own token still matters for relying parties that stay on v0.2 (delegus-base-v1), whose T2 reads only the Principal's own verification. One file serves both: { "token": "<the Principal's token>", "tokens": ["<the claim token>"] }, and both _delegus.<domain> TXT records may coexist.

What /verify answers before the domain is verified#

These are refusals, not decisions. They come before any check runs, so there is no receipt, and the agent's Proof is not spent: the same Proof works once the problem is fixed.

HTTPerrorWhen
403RP_UNVERIFIEDYour relying party is on your own domain and your organization's claim on it is not verified (pending, lapsed, expired, closed, or none).
403RP_SUSPENDEDDelegus has suspended your relying party or marked it disputed, for example after a misuse report. Write to hello@delegus.ai.

RP_SUSPENDED is checked first. Relying parties Delegus hosts (did:web:delegus.ai:rp:<slug>) never get RP_UNVERIFIED. The same refusals apply to the AuthZEN evaluation endpoint. With the SDK, both arrive as a DelegusApiError with status 403 and code set to the value above.

Going live is refused the same way: production cannot be turned on for an organization without a verified domain (the API's error is PRODUCTION_REQUIRES_DOMAIN; the console tells you when you pick a plan). Sandbox checks are not affected.

Errors when you claim#

Every error body is { "error": "<code>", "message": "..." }. Some also carry terms_url.

HTTPerrorMeaning
400TERMS_REQUIREDterms is missing, or is not exactly { accepted_by, accepted_at, version } with valid values.
400CLAIM_DOMAIN_INVALIDNot a domain name (for example an IP address, a single word, or a trailing dot); a public suffix such as co.uk or github.io; or a domain Delegus manages (delegus.ai and anything under it).
403CLAIM_FREE_EMAILThe signed-in email is at a free email provider. Includes terms_url.
403CLAIM_EMAIL_MISMATCHThe signed-in email is not at the claimed domain or a domain above it within the same registered domain (see the table above), or has no valid domain. Includes terms_url.
409CLAIM_DOMAIN_VERIFIEDAnother organization already owns this domain (verified or lapsed).
409CONFLICTYour organization already has an open claim on this domain. Use that one.

The check behind CLAIM_EMAIL_MISMATCH and CLAIM_DOMAIN_INVALID uses the Public Suffix List (the public list of domain endings such as .com and .co.uk), and each claim records which version was used.

Claiming, verifying and using a domain are covered by Acceptable use in the Terms (section 7.11).