{"openapi":"3.1.0","info":{"title":"PaywallWatch","version":"1","description":"Email address screening for agents, paid per call over x402. Syntax, DNS mail exchanger, disposable-domain list, role-account, free-provider and typo heuristics. It does not verify that the mailbox exists.","x-guidance":"Use GET /v1/email/verify?email=<address> ($0.003 per call) to screen one email address: syntax, DNS mail exchanger, disposable domain, role account, free provider and common typos. It does not verify that the mailbox exists. GET /v1/ping ($0.01) only proves that your client can pay a 402. Pay in USDC over x402 v2: an unpaid GET answers 402 with the terms in the PAYMENT-REQUIRED header; no account, no API key.","contact":{"url":"https://paywallwatch.com","email":"support@auraaia.com"}},"externalDocs":{"url":"https://paywallwatch.com/quickstart","description":"Quickstart: a runnable first paid check"},"servers":[{"url":"https://api.paywallwatch.com"}],"paths":{"/v1/ping":{"get":{"operationId":"ping","summary":"GET /v1/ping ($0.01 per call)","description":"Use when testing an x402 client end to end. Returns ok and the server time; costs one cent.","tags":["x402","ping","test","health-check"],"security":[],"parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"},"description":"The x402 v2 payment payload (base64 JSON): a USDC authorization that an x402 client builds from the terms in the PAYMENT-REQUIRED header of the unpaid 402 and signs with the buyer's wallet, then sends with the repeated request. This is not an API key and there is nothing to register for: a client generated from this document cannot produce it, because producing it means signing a payment with a funded wallet. Use an x402 client such as @x402/fetch, which reads the 402 and repeats the request with this header. Omit it to read the terms without paying."}],"responses":{"200":{"description":"The result, charged $0.01 and settled on the network you paid on; the settlement is in the PAYMENT-RESPONSE header (base64 JSON). The result is computed before settlement and released only once settlement succeeds. The schema is closed (additionalProperties false): the body has exactly the fields listed, and a new field would be a contract change announced in this document, not a silent addition.","headers":{"PAYMENT-RESPONSE":{"description":"The settlement: success, payer, network, transaction (base64 JSON, x402 v2).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","description":"A paid test call. additionalProperties is false: the body has exactly these fields; a new field would be a contract change, not a silent addition.","properties":{"ok":{"type":"boolean","const":true},"at":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"The server time. The shape of Date.toISOString() in UTC; a shape check, not a calendar check."}},"required":["ok","at"],"additionalProperties":false},"example":{"ok":true,"at":"2026-10-20T09:12:00Z"}}}},"402":{"description":"Payment required, not charged: no valid payment was sent. The terms ($0.01 in USDC, the networks, the receiving address, the input and output schemas) are in the PAYMENT-REQUIRED header (base64 JSON, x402 v2), which is authoritative; x402 v2 does not define the body. What this service sends as the body depends on the client: an API client (any request that is not a browser's) gets application/json with an empty object; a browser (Accept includes text/html and a Mozilla user agent) gets a small HTML payment page (text/html). A payment the facilitator rejects (signature, balance, network) gets this answer too and is not charged.","headers":{"PAYMENT-REQUIRED":{"description":"The payment terms (base64 JSON, x402 v2): the authoritative place to read them, whatever the body.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{}},"text/html":{"schema":{"type":"string"}}}},"429":{"description":"Too many unpaid requests from one address (a best-effort throttle on the unpaid 402s); not charged. Pay to continue.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"What was wrong, in a sentence."}},"required":["error"],"additionalProperties":false},"example":{"error":"too many unpaid requests; pay to continue"}}}},"503":{"description":"The service could not answer and Retry-After is set; not charged, settlement is cancelled. Try again later.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.01"},"protocols":[{"x402":{}}]},"x-x402":{"price":"$0.01","asset":"USDC","networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]}}},"/v1/email/verify":{"get":{"operationId":"emailVerify","summary":"GET /v1/email/verify ($0.003 per call)","description":"Use when an agent needs email validation, screening only, for an address from a form, a scrape or a CRM and must decide whether it is worth sending to. Screens the address: syntax, DNS mail exchanger, disposable domain, role account, free provider and common typos. It does not verify that the mailbox exists. A DNS failure answers 503 and is not charged.","tags":["email","email-validation","email-screening","lead","crm","disposable-email","email-check","mx","dns","deliverability"],"security":[],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string"},"description":"The address to screen","example":"jane@iana.org"},{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"},"description":"The x402 v2 payment payload (base64 JSON): a USDC authorization that an x402 client builds from the terms in the PAYMENT-REQUIRED header of the unpaid 402 and signs with the buyer's wallet, then sends with the repeated request. This is not an API key and there is nothing to register for: a client generated from this document cannot produce it, because producing it means signing a payment with a funded wallet. Use an x402 client such as @x402/fetch, which reads the 402 and repeats the request with this header. Omit it to read the terms without paying."}],"responses":{"200":{"description":"The result, charged $0.003 and settled on the network you paid on; the settlement is in the PAYMENT-RESPONSE header (base64 JSON). The result is computed before settlement and released only once settlement succeeds. The schema is closed (additionalProperties false): the body has exactly the fields listed, and a new field would be a contract change announced in this document, not a silent addition.","headers":{"PAYMENT-RESPONSE":{"description":"The settlement: success, payer, network, transaction (base64 JSON, x402 v2).","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","description":"One email screening: syntax, DNS mail exchanger, disposable-domain list, role-account, free-provider and typo heuristics. It does not verify that the mailbox exists or that mail will be delivered. additionalProperties is false: the body has exactly these fields; a new field would be a contract change, not a silent addition.","properties":{"email":{"type":"string","description":"The address as screened: trimmed and lower-cased."},"valid_syntax":{"type":"boolean","description":"Well formed (RFC-style local part and domain). When false, nothing else was checked."},"dns_status":{"type":"string","enum":["ok","implicit","null_mx","nomx","nxdomain","not_checked"],"description":"ok: MX records exist. implicit: no MX, an A record stands in. null_mx: the domain declares it accepts no mail. nomx: neither MX nor A. nxdomain: no such domain. not_checked: the syntax check failed first. (error occurs only on the uncharged 503.)"},"has_mx":{"type":"boolean","description":"True only when dns_status is ok. A mail exchanger means the domain accepts mail, never that the mailbox exists."},"disposable":{"type":"boolean","description":"The domain is on a public list of throwaway providers."},"role_account":{"type":"boolean","description":"A shared inbox such as info@ or sales@. A flag for your own rules; it never changes the verdict."},"free_provider":{"type":"boolean","description":"A consumer mail provider such as gmail.com. A flag for your own rules; it never changes the verdict."},"suggestion":{"type":["string","null"],"description":"A corrected address when a common typo is suspected, otherwise null. Ask the person to confirm it."},"verdict":{"type":"string","enum":["domain_accepts_mail","risky","disposable","undeliverable"],"description":"domain_accepts_mail: route it. risky: a typo is suspected or only an A record stands in for MX. disposable: hold it. undeliverable: the syntax or the domain rules it out. (unknown occurs only on the uncharged 503.)"},"reasons":{"type":"array","items":{"type":"string","enum":["invalid_syntax","domain_not_found","null_mx","no_mail_exchanger","no_mx_record_only_a_record","disposable_domain","typo_suspected"]},"description":"Why, possibly empty. (dns_lookup_failed occurs only on the uncharged 503.)"},"mailbox_verified":{"type":"boolean","const":false,"description":"Always false. No SMTP conversation takes place; this is screening, not mailbox verification."},"screening_note":{"type":"string","description":"The same limitation in a sentence."},"checked_at":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When the check ran. The shape of Date.toISOString() in UTC; a shape check, not a calendar check."}},"required":["email","valid_syntax","dns_status","has_mx","disposable","role_account","free_provider","suggestion","verdict","reasons","mailbox_verified","screening_note","checked_at"],"additionalProperties":false},"example":{"email":"jane@iana.org","valid_syntax":true,"dns_status":"ok","has_mx":true,"disposable":false,"role_account":false,"free_provider":false,"suggestion":null,"verdict":"domain_accepts_mail","reasons":[],"mailbox_verified":false,"screening_note":"Screening only: syntax, DNS mail exchanger, disposable-domain list, role-account and typo heuristics. It does not verify that the mailbox exists or that mail will be delivered.","checked_at":"2026-10-20T09:12:00Z"}}}},"400":{"description":"A payment was sent but the request carried no usable email; refused before the facilitator is asked, not charged.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"What was wrong, in a sentence."}},"required":["error"],"additionalProperties":false},"example":{"error":"email query parameter is required"}}}},"402":{"description":"Payment required, not charged: no valid payment was sent. The terms ($0.003 in USDC, the networks, the receiving address, the input and output schemas) are in the PAYMENT-REQUIRED header (base64 JSON, x402 v2), which is authoritative; x402 v2 does not define the body. What this service sends as the body depends on the client: an API client (any request that is not a browser's) gets application/json with an empty object; a browser (Accept includes text/html and a Mozilla user agent) gets a small HTML payment page (text/html). A payment the facilitator rejects (signature, balance, network) gets this answer too and is not charged.","headers":{"PAYMENT-REQUIRED":{"description":"The payment terms (base64 JSON, x402 v2): the authoritative place to read them, whatever the body.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"},"example":{}},"text/html":{"schema":{"type":"string"}}}},"429":{"description":"Too many unpaid requests from one address (a best-effort throttle on the unpaid 402s); not charged. Pay to continue.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"What was wrong, in a sentence."}},"required":["error"],"additionalProperties":false},"example":{"error":"too many unpaid requests; pay to continue"}}}},"503":{"description":"The check could not be completed: the DNS lookup failed, so nothing is known about the domain. The body is the screening with verdict unknown and error dns_unavailable; Retry-After is set; not charged, settlement is cancelled. Try again later.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"The DNS lookup failed, so nothing is known about the domain: HTTP 503 with Retry-After, settlement cancelled, not charged. The other heuristics are still reported. additionalProperties is false: the body has exactly these fields; a new field would be a contract change, not a silent addition.","properties":{"email":{"type":"string","description":"The address as screened: trimmed and lower-cased."},"valid_syntax":{"type":"boolean","description":"Well formed (RFC-style local part and domain). When false, nothing else was checked."},"dns_status":{"type":"string","const":"error","description":"The resolver failed (SERVFAIL, REFUSED, HTTP error or timeout)."},"has_mx":{"type":"boolean","description":"True only when dns_status is ok. A mail exchanger means the domain accepts mail, never that the mailbox exists."},"disposable":{"type":"boolean","description":"The domain is on a public list of throwaway providers."},"role_account":{"type":"boolean","description":"A shared inbox such as info@ or sales@. A flag for your own rules; it never changes the verdict."},"free_provider":{"type":"boolean","description":"A consumer mail provider such as gmail.com. A flag for your own rules; it never changes the verdict."},"suggestion":{"type":["string","null"],"description":"A corrected address when a common typo is suspected, otherwise null. Ask the person to confirm it."},"verdict":{"type":"string","const":"unknown","description":"Nothing is known about the domain."},"reasons":{"type":"array","items":{"type":"string","enum":["invalid_syntax","domain_not_found","null_mx","no_mail_exchanger","no_mx_record_only_a_record","dns_lookup_failed","disposable_domain","typo_suspected"]},"description":"Why; dns_lookup_failed, plus any heuristic that still applied."},"mailbox_verified":{"type":"boolean","const":false,"description":"Always false. No SMTP conversation takes place; this is screening, not mailbox verification."},"screening_note":{"type":"string","description":"The same limitation in a sentence."},"checked_at":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$","description":"When the check ran. The shape of Date.toISOString() in UTC; a shape check, not a calendar check."},"error":{"type":"string","const":"dns_unavailable"}},"required":["email","valid_syntax","dns_status","has_mx","disposable","role_account","free_provider","suggestion","verdict","reasons","mailbox_verified","screening_note","checked_at","error"],"additionalProperties":false},"example":{"email":"jane@gmial.com","valid_syntax":true,"dns_status":"error","has_mx":false,"disposable":false,"role_account":false,"free_provider":false,"suggestion":"jane@gmail.com","verdict":"unknown","reasons":["dns_lookup_failed","typo_suspected"],"mailbox_verified":false,"screening_note":"Screening only: syntax, DNS mail exchanger, disposable-domain list, role-account and typo heuristics. It does not verify that the mailbox exists or that mail will be delivered.","error":"dns_unavailable","checked_at":"2026-10-26T18:25:37Z"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.003"},"protocols":[{"x402":{}}]},"x-x402":{"price":"$0.003","asset":"USDC","networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"]}}}},"x-agentcash-guidance":{"llmsTxtUrl":"https://paywallwatch.com/llms.txt"},"x-x402":{"protocol":"x402","version":2,"asset":"USDC","networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"],"how":"An unpaid GET answers 402 with the terms in the PAYMENT-REQUIRED header; pay the exact amount with an x402 client and repeat the request. No account, no API key."}}