Look at a domain
Which common addresses at a domain its mail server accepted (or reported full), and whether the domain accepts mail for every address. The domain's mail servers are read to decide whether a search can start, but they are not returned.
This GET starts work and charges. The first call for an uncached domain claims the domain, deducts 10 credits, enqueues every candidate to the verification worker, and returns immediately with status: "processing" and an empty emails array. That empty array is not the answer: it means the search has just begun.
Repeat the same GET to poll. Each poll assembles whatever this search's own checks have finished (results other checks left in the shared cache are not used, and an address is listed only when a mail server accepted it or reported its mailbox full); when every candidate has a definite answer, the domain turns out to be catch-all, or the job ages out (about 30 seconds), it returns status: "completed". A complete search is cached for 7 days. A candidate counts as checked only on a definite answer: a found mailbox, or a definite no (invalid, disposable, spam_trap). An answer that settles nothing (unknown, risky without mailbox evidence, a policy_block, greylisted, temporary_failure, connection_failure or dns_only result, or no answer at all) does not, so a search where some candidates got no definite answer ends as completion_reason: "time_limit_reached" with patterns_checked below the total. That partial result is kept for 15 minutes, not 7 days; the next search after that runs (and charges) afresh. The poll that completes a partial search refunds the unchecked share of the 10 credits to the account that started it, in half credits rounded in the customer's favour (nothing checked refunds all 10), and reports it as credits_refunded. Polling never charges again (the owner paid at the first call), and a search served from that 7-day cache charges nothing at all: it answers credits_used: 0 for the owner and for anyone else.
A domain that cannot receive mail is answered before anything is charged. Before a new search is started, the domain's mail servers are read the way the verifier reads them: an MX record with a real host, or, with no MX at all, the domain's own A or AAAA address (RFC 5321's implicit MX). A domain that does not exist, publishes a null MX (RFC 7505), or has neither an MX nor an address is a 400 saying which, with nothing searched and no credits charged: no mailbox can exist there. Such a search used to be queued and billed 10 credits for 46 answers known in advance. A lookup that fails (no answer, SERVFAIL) is a 503, also uncharged; retry it. A domain under a special-use top-level name (.example, .test, .invalid, .localhost, .local, .internal and the other special-use names listed under POST /v1/find) is a 400 before anything is read.
A public mailbox provider is a 400 before anything is charged. gmail.com, yahoo.com, outlook.com and the other domains POST /v1/verify reports free_provider: true for hold mailboxes of unrelated individuals, not one organization, so their common addresses would only list strangers' mailboxes. A cached result for one is not served; a search already running for one still finishes for the account that paid for it.
Searches that are not paid for in full are limited to 20 per account per UTC day. A search counts from the moment it starts until its result is collected. One that completes with every mailbox answered, or as a catch-all domain, keeps its charge and stops counting; one that ends time_limit_reached (and is refunded the unchecked share) counts for the rest of the day, and so does one nobody has polled to completion yet. At the limit a new search is a 429 with retry_after_seconds (and Retry-After) up to midnight UTC, and nothing is claimed, queued or charged. Polling a search, and a domain served from the cache, never count and are never refused by it. Without it an account could start search after refunded search at no cost while each one still ran its 46 checks against mail servers it picked.
Treating the first response as the finished result is the mistake this endpoint invites: you have paid for a search and read none of it.
Request
- Base URL: https://api.kawaa.com
- URL: https://api.kawaa.com/v1/domain/{domain}
- Auth: one of:
- API key in header X-Api-Key
- HTTP bearer
- OAuth 2 (authorization code, authorization URL https://api.kawaa.com/oauth/authorize, token URL https://api.kawaa.com/oauth/token, scopes: verification:write)
Path parameters
A bare registrable domain name. Normalized before it is validated, which is why no format: hostname or pattern is declared here: the API trims, lower-cases, punycodes an internationalized domain and then strips ONE leading www., in that order, because IDNA maps the Unicode label separators (。, ., 。) to ., so www。münchen.de only grows its ASCII dot during the fold. Only then is the format checked. So " WWW.Example.COM " and münchen.de are both accepted; the latter is checked as xn--mnchen-3ya.de, the same fold /v1/verify applies to the domain half of an address. A scheme, a path or a port is NOT stripped and is a 400 Invalid domain format; send the host on its own. At least two labels are required, each label 1–63 characters, and the TLD either letters only and at least two (com, de) or a decodable xn-- A-label of an internationalized one (пример.рф is checked as xn--e1afmkfd.xn--p1ai). The A-label must decode AND be the canonical spelling of what it decodes to, not merely carry the prefix: example.xn--abc decodes to nothing, and example.xn---7a decodes to ¡ whose one canonical form is xn--7a. Neither can name a TLD any root zone holds, so both are refused rather than charged for.
Response
The search, in whichever state it is in. status is the field to branch on: processing means the work has started and emails is empty because nothing has finished yet, NOT that the domain has no addresses.
Changes
No recorded changes to this operation across all 1 revision of this API.