Skip to content

Domain verification (Verified host)

Notifly can scan ports of an arbitrary host. To prevent this from being used to attack someone else’s infrastructure, public hosts must first have their ownership verified — prove that the host is actually yours. A Verified host is a record “user X owns host Y” with a validity period of 365 days.

After verification, scanning that host runs in a faster mode (larger port batches and higher concurrency); unverified hosts can still be scanned, but more cautiously and slowly.

Ownership can be verified with one of two methods (method):

methodWhat to placeWhere Notifly checks
dnsDNS TXT record _notifly-verify.<host> with value = tokenresolves TXT via the system DNS resolver
httpfile /.well-known/notifly-verify.txt, single line = tokenGET https://<host>/.well-known/notifly-verify.txt, fallback to http:// on failure

The token is a random UUID that Notifly issues at the start step. During checking the TXT record value (or the file content) is compared to the token after trimming whitespace (strings.TrimSpace), so extra spaces and a trailing newline won’t prevent verification.

If a host resolves only to private addresses, ownership does not need to be confirmed — such a record is created automatically with method auto-private.

Private addresses include (checked by the IsPrivateHost function):

  • localhost;
  • loopback 127.0.0.0/8 and ::1/128;
  • RFC 1918 — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16;
  • link-local 169.254.0.0/16 and fe80::/10;
  • RFC 4193 ULA fc00::/7.

For loopback addresses and localhost verification via DNS/HTTP is not possible in principle, so they are always considered verified.

POST /verified-host/start returns a different status depending on the host:

statusWhenHTTP code
already_verifiedthere is already a valid (non-expired) record for this host — returned in the host field200
verifiedhost is private, record created automatically (method: "auto-private")201
pendingpublic host — token and instruction issued, waiting for your step and check200

A pending record is not saved anywhere until a successful check: you must remember the token on the client and send it back in /verified-host/check.

Окно терминала
curl -X POST "$NOTIFLY_URL/verified-host/start" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{ "host": "example.com", "method": "dns" }'

Response for a public host:

{
"status": "pending",
"token": "550e8400-e29b-41d4-a716-446655440000",
"method": "dns",
"host": "example.com",
"instruction": "Create a DNS TXT record: _notifly-verify.example.com with value: 550e8400-e29b-41d4-a716-446655440000"
}

Method dns — create a TXT record in the domain zone:

_notifly-verify.example.com. IN TXT "550e8400-e29b-41d4-a716-446655440000"

Method http — put a file at /.well-known/notifly-verify.txt so it is served at:

https://example.com/.well-known/notifly-verify.txt

The file content should be exactly the token, a single line:

550e8400-e29b-41d4-a716-446655440000

Provide host, method and token to check. Wait for DNS propagation (TTL may be a few minutes) before calling:

Окно терминала
curl -X POST "$NOTIFLY_URL/verified-host/check" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"host": "example.com",
"method": "dns",
"token": "550e8400-e29b-41d4-a716-446655440000"
}'

On success — the record is created, returns code 201 and the object itself:

{
"id": 42,
"host": "example.com",
"method": "dns",
"verifiedAt": "2026-06-23T10:00:00Z",
"expiresAt": "2027-06-23T10:00:00Z"
}

If the token is not found (TXT not propagated, file unavailable, value mismatch) — a 422 code will be returned with an explanation in the error field, for example token not found in TXT records for _notifly-verify.example.com or HTTP 404 from https://example.com/.well-known/notifly-verify.txt. Simply retry check after fixing the issue.

List of the user’s active (non-expired) verifications:

Окно терминала
curl "$NOTIFLY_URL/verified-host" \
-H "X-Notifly-Key: <client-token>"
[
{
"id": 42,
"host": "example.com",
"method": "dns",
"verifiedAt": "2026-06-23T10:00:00Z",
"expiresAt": "2027-06-23T10:00:00Z"
}
]

Delete a verification (for example, if the host is no longer yours):

Окно терминала
curl -X DELETE "$NOTIFLY_URL/verified-host/42" \
-H "X-Notifly-Key: <client-token>"
# → {"ok":true}

You can only delete your record: someone else’s or a non-existent id will return 404.

All endpoints require a client (or MCP) token. Base URL — $NOTIFLY_URL (https://notifly.ru), auth header — X-Notifly-Key.

MethodPathDescription
GET/verified-hostList of the user’s active verifications
POST/verified-host/startStart verification: { "host", "method" }, where method = dns or http. Returns status (already_verified / verified / pending) and for a public host — token + instruction
POST/verified-host/checkVerify the placed proof: { "host", "method", "token" }. Success → 201 and the record object; failure → 422 with error
DELETE/verified-host/:idDelete your verification by id (other/non-existent → 404)

Fields of the VerifiedHost object: id, host, method (dns / http / auto-private), verifiedAt, expiresAt. The token is not returned in the response.