CLI reference
The same library, driven from a shell. Useful for auditing a domain, checking a list, or sanity-checking a signup rule before wiring it into code.
Install
go install github.com/bakhod1r/emailx/cmd/emailx@latest
emailx <command> [flags] [arguments]
analyze <email> full intelligence profile for one address
validate <email> syntax, domain, and DNS validation
domain <domain> SPF, DMARC, DKIM, MX and transport-security records
verify <email> SMTP mailbox probe
batch <file|-> validate a list of addresses, one per line or CSV
Global flags
Every command accepts these.
| Flag | Default | Meaning |
|---|---|---|
-json | off | emit JSON instead of text |
-timeout | 10s | deadline per address |
-dns | system | DNS server as host:port, queried directly so TTLs are visible |
-cache | 5m | cache DNS answers for this long; 0 disables |
Ctrl-C cancels lookups in flight rather than leaving them hanging.
analyze
Everything the library knows about one address, in one pass.
$ emailx analyze john@example.com
Address: john@example.com
Domain: example.com
Valid: yes
Disposable: no
Role account: no
Free provider: no
MX: yes (mail.example.com.)
SPF: yes (-all, 3 lookups)
DMARC: yes (p=reject, pct=100, enforcing)
DKIM: yes (selector selector1)
Protected: yes
Risk: LOW (0)
Deliverability: 100/100
Every risk signal and every deliverability deduction is printed on its own line, so a score can always be traced back to its cause.
validate
A narrower check: syntax, domain, and whether the DNS backs it up. Exits non-zero when the address is not valid, so it drops into scripts.
$ emailx validate user@example.com -json
{
"address": "user@example.com",
"valid": true,
"syntax": true,
"domain": true,
"mx": true,
"spf": true,
"dmarc": true,
"dkim": false,
"protected": false,
"disposable": false,
"role": false
}
domain
Audits a domain rather than an address. This is the command to reach for when someone asks whether a domain is configured correctly.
$ emailx domain google.com
Domain: google.com
MX: yes (smtp.google.com.)
SPF: yes (~all, 1 lookup)
DMARC: yes (p=reject, pct=100, enforcing)
DKIM: no key found on the common selectors
Protected: no
DNSSEC: no BIMI: no MTA-STS: yes TLS-RPT: yes
| Flag | Meaning |
|---|---|
-selectors | comma-separated DKIM selectors to probe instead of the common list |
A "no key found" result does not prove there is no DKIM — it means none of the common selectors answered. If you know the selector, pass it.
verify
Opens an SMTP connection and asks the server about the mailbox.
$ emailx verify -skip-catch-all -timeout 5s postmaster@gmail.com
Address: postmaster@gmail.com
Status: valid
MX host: gmail-smtp-in.l.google.com
Reply: 250
STARTTLS: yes
Took: 862ms
| Flag | Default | Meaning |
|---|---|---|
-helo | localhost | hostname sent in EHLO; should resolve back to your IP |
-from | empty | envelope sender; empty sends the null sender <> |
-rate | 0 | maximum probes per second; 0 is unthrottled |
-skip-catch-all | off | skip the second, random-address probe |
This command sends real SMTP traffic to someone else's
server. Most cloud providers block outbound port 25, so expect
unknown unless the network allows it. Unthrottled probing
gets the sending IP blocklisted — use -rate. A
catch-all status means the server accepts every address, so
acceptance says nothing about the mailbox, and a 4xx reply is
greylisting reported as unknown, never as
invalid.
batch
Runs analyze over a list and writes a table. Reads a file,
or - for standard input.
$ emailx batch addresses.csv -column 1 -header
address,valid,mx,protected,disposable,role,risk,deliverability,error
ada@gmail.com,true,true,false,false,false,LOW,80,
bad-address,false,false,false,false,false,,0,emailx: invalid syntax
user@mailinator.com,true,true,true,true,false,MEDIUM,70,
| Flag | Default | Meaning |
|---|---|---|
-concurrency | 10 | addresses processed at once |
-column | 0 | zero-based CSV column holding the address |
-header | off | skip the first line |
A plain list of addresses, one per line, needs no flags — rows with no comma are taken verbatim. Rows may have differing column counts.
Leave -cache at its default. A list with many addresses on
the same domain then costs one set of lookups per domain rather than per
address.
$ cat addresses.txt | emailx batch - -json -concurrency 25
Exit codes
| Code | Meaning |
|---|---|
0 | the command completed |
1 | bad usage, a parse failure, an invalid address from validate, or an unreadable input file |
batch reports per-address failures in the error
column and still exits 0; one bad address in a list of
thousands is data, not a command failure.