Documentation
Ping250 docs
Everything the tool does, how the SMTP flow works under the hood, and how to script it.
How a test works, end to end
Every action is a single HTTP POST from your browser to a server-side route. Credentials live only in that request body. The route validates the input with Zod, runs the same-origin check, the per-IP rate limiter and the bot check, then builds a throwaway Nodemailer transport, does the work, closes the transport, and returns a structured result. Nothing is written to a log, a database, or disk.
browser ──POST /api/smtp/send──▶ route handler
│ │ 1. Zod validation
│ { config, message, │ 2. same-origin (CSRF) check
│ turnstileToken } │ 3. per-IP rate limit (Upstash)
│ │ 4. Cloudflare Turnstile verify
│ │ 5. createTransport(config)
│ │ 6. transporter.verify()
│ │ 7. transporter.sendMail(message)
│◀── { ok, latencyMs, … } ────────┘ 8. transport.close()Ports and TLS, the part everyone gets wrong
Most failed tests are a port/TLS mismatch. The secure flag must match the port: implicit TLS on 465, STARTTLS on 587.
| Port | Mode | Notes |
|---|---|---|
| 465 | Implicit TLS | secure = true. The connection is encrypted from the first byte. Preferred when offered. |
| 587 | STARTTLS | secure = false. Starts plain, then upgrades to TLS via STARTTLS. The modern submission standard. |
| 25 | Usually plain | Server-to-server relay. Blocked for outbound by most clouds and ISPs - avoid for testing. |
Error glossary
Failures are mapped from Nodemailer's machine codes (EAUTH, ECONNECTION, ETIMEDOUT, EENVELOPE…) and the server's SMTP reply into a plain title, an explanation, and a next step.
Authentication failed
The server rejected the username/password (SMTP 535), or wants auth before talking (530).
Fix: Check the credentials. Gmail/Zoho/Fastmail need an app password. SendGrid's username is the literal string “apikey”.
Connection timed out
No response within the timeout (ETIMEDOUT).
Fix: Confirm the port and TLS mode line up, and that no firewall blocks egress. Port 25 is commonly blocked.
Host not found
The hostname did not resolve in DNS (ENOTFOUND).
Fix: Fix the host spelling - smtp.gmail.com, not smtp.gmail.co.
TLS handshake failed
The encrypted session could not be set up (EPROTOCOL / certificate errors).
Fix: Match port to TLS mode (465 = secure on, 587 = secure off). Self-signed certs on internal servers need explicit trust.
Recipient address rejected
The server refused the To (or From) address (550 / 5.1.1).
Fix: Send to an address you control. Some servers require From to equal the authenticated account.
Rejected by server policy
Accepted the connection, refused the message (5.7.x) - spam, relay or reputation.
Fix: Check SPF/DKIM/DMARC with the diagnostics tab. New IPs are often throttled.
SPF, DKIM and DMARC in one paragraph each
SPF lists which servers may send for your domain. A record ending in -all (hard fail) is strongest; ~all (soft fail) is common; +all authorises the entire internet and is a hole.
DKIM signs each message so receivers can prove it was not altered in transit. It lives at selector._domainkey.domain; the diagnostics tab tries the common selectors.
DMARC tells receivers what to do when SPF or DKIM fails - p=none only reports, p=quarantine sends to spam, p=reject refuses outright.
HTTP API
The same logic the UI uses is exposed as JSON routes. A failed SMTP action returns HTTP 200 with ok: false and a structured error; HTTP 4xx is reserved for validation, rate-limit and bot-check faults.
POST /api/smtp/verify
{ "config": { "host", "port", "secure", "username", "password", "fromName", "fromEmail" },
"turnstileToken": "…" }
POST /api/smtp/send
{ "config": { … },
"message": { "to", "subject", "text"?, "html"?, "attachment"? },
"turnstileToken": "…" }
POST /api/diagnostics
{ "domain": "acme.dev", "turnstileToken": "…" }With Turnstile enabled in production, programmatic callers must supply a valid token. For local scripting, set NEXT_PUBLIC_TURNSTILE_ENABLED=false and the routes are gated only by the rate limiter. A dedicated, separately-authenticated API mode for CI/CD is on the roadmap.
Security and abuse prevention
This tool relays real mail through user-supplied credentials, so it is treated as a potential open-relay vector. In v1: every field is Zod-validated; recipients are capped at one per request; sends are gated by Cloudflare Turnstile plus a per-IP sliding-window rate limit (Upstash in production, in-memory for local dev); and a same-origin check blocks cross-site request forgery from browsers. Credentials are never logged, stored, or persisted server-side.
Saved profiles are encrypted in the browser with AES-256-GCM under a key derived from your passphrase via PBKDF2-SHA256 (210,000 iterations). Only ciphertext, salt and IV are stored in localStorage; the passphrase never leaves the page.