SDKs
Official, typed clients for the v1 API in four languages. Each one covers the full public surface — single verification, batch jobs, ESP integrations and keyword rules, usage reports — and handles auth, retries, and idempotency for you.
Language | Package | Requires |
|---|---|---|
Node.js / TypeScript | Node.js 18+ | |
Python | Python 3.9+ | |
Ruby | Ruby 2.6+ | |
Go | Go 1.24+ |
All four are MIT-licensed and zero-dependency (standard library only), retry 429/5xx responses honoring Retry-After, and attach an Idempotency-Key to every POST so a retried batch submit never double-charges.
You don't need an SDK — every endpoint is plain HTTP + JSON, as shown in the Quickstart. The SDKs just save you the plumbing.
Authentication
Every client sends your key as Authorization: Bearer <key> (see Authentication). Get your key from the dashboard under Settings → API.
The recommended setup is the MAILFLOSS_API_KEY environment variable — each client reads it when constructed with no arguments, which keeps the key out of your source tree:
export MAILFLOSS_API_KEY="mf_live_your_key_here"You can also pass the key explicitly (shown per language below). If no key is found, the constructor raises a configuration error rather than failing later on the first request.
Install and verify an email
Node.js / TypeScript
npm install @mailfloss/sdkimport { Mailfloss } from "@mailfloss/sdk";
// Reads MAILFLOSS_API_KEY, or pass it: new Mailfloss({ apiKey: "mf_live_..." })
const mailfloss = new Mailfloss();
const result = await mailfloss.verify({ email: "[email protected]" });
console.log(result.status); // "passed" | "undeliverable" | "risky" | "unknown"
console.log(result.passed); // true when safe to send
console.log(result.reason); // e.g. "available"
console.log(result.suggestion); // typo fix, when one is detectedPython
pip install mailflossfrom mailfloss import Mailfloss
# Reads MAILFLOSS_API_KEY, or pass it: Mailfloss(api_key="mf_live_...")
client = Mailfloss()
result = client.verify("[email protected]")
print(result["status"]) # "passed" | "undeliverable" | "risky" | "unknown"
print(result["passed"]) # True when safe to send
print(result["reason"]) # e.g. "available"
if result.get("suggestion"):
print("Did you mean:", result["suggestion"])Ruby
gem install mailflossrequire "mailfloss"
# Reads MAILFLOSS_API_KEY, or pass it: Mailfloss::Client.new(api_key: "mf_live_...")
client = Mailfloss::Client.new
result = client.verify(email: "[email protected]")
result[:status] # "passed" | "undeliverable" | "risky" | "unknown"
result[:passed] # true when safe to send
result[:reason] # e.g. "available"
result[:suggestion] # typo fix, when one is detectedResponses are parsed with symbol keys.
Go
go get github.com/mailfloss/mailfloss-gopackage main
import (
"context"
"fmt"
"log"
mailfloss "github.com/mailfloss/mailfloss-go"
)
func main() {
// Reads MAILFLOSS_API_KEY, or pass it: mailfloss.New(mailfloss.WithAPIKey("mf_live_..."))
client, err := mailfloss.New()
if err != nil {
log.Fatal(err)
}
res, err := client.Verify.Check(context.Background(), mailfloss.VerifyParams{
Email: "[email protected]",
})
if err != nil {
log.Fatal(err)
}
// Status is one of: passed, undeliverable, risky, unknown
fmt.Printf("%s -> %s (%s) passed=%t\n", res.Email, res.Status, res.Reason, res.Passed)
}Batch verification
Submit a job, poll its status, then page through results — the same flow as the Quickstart, one method per step. Pass an optional webhook_url to be notified on completion instead of polling.
Node.js / TypeScript
const { id } = await mailfloss.batchVerify.create({
emails: ["[email protected]", "[email protected]"],
webhook_url: "https://example.com/hooks/mailfloss", // optional; omit to poll
});
const { status, progress } = await mailfloss.batchVerify.status(id);
const page = await mailfloss.batchVerify.results(id, { per_page: 100 });
console.log(page.results);Python
job = client.batch_verify.create(
emails=["[email protected]", "[email protected]"],
webhook_url="https://example.com/hooks/mailfloss", # optional; omit to poll
)
status = client.batch_verify.status(job["id"])
print(status["status"], status.get("progress"))
page = client.batch_verify.results(job["id"], per_page=500)
for row in page.get("results", []):
print(row)Ruby
batch = client.batch_verify.create(
emails: ["[email protected]", "[email protected]"],
webhook_url: "https://example.com/hooks/mailfloss" # optional; omit to poll
)
status = client.batch_verify.status(batch[:id])
puts "#{status[:status]} #{status[:progress]}"
page = client.batch_verify.results(batch[:id], per_page: 100)
page[:results]Go
job, err := client.BatchVerify.Create(ctx, mailfloss.BatchVerifyCreateParams{
Emails: []string{"[email protected]", "[email protected]"},
WebhookURL: "https://example.com/hooks/mailfloss", // optional; omit to poll
})
status, err := client.BatchVerify.Status(ctx, job.ID)
fmt.Printf("job %s: %s (%.0f%%)\n", job.ID, status.Status, status.Progress)
page, err := client.BatchVerify.Results(ctx, job.ID, mailfloss.BatchVerifyResultsParams{
PerPage: 1000,
})
for _, r := range page.Results {
fmt.Printf("%s -> %s (%s)\n", r.Email, r.Status, r.Reason)
}Errors
Non-2xx responses surface as a language-native error carrying the same fields as the JSON envelope documented in Errors — status, code, message, type, and request_id. Branch on the stable code, never on message.
Language | Error type |
|---|---|
Node.js / TypeScript | MailflossError (config problems: MailflossConfigError) |
Python | MailflossError (config problems: MailflossConfigError) |
Ruby | Mailfloss::APIError (config problems: Mailfloss::ConfigurationError; both subclass Mailfloss::Error) |
Go | *mailfloss.Error, matched with errors.As |
from mailfloss import Mailfloss, MailflossError
try:
client.jobs.get("does-not-exist")
except MailflossError as err:
print(err.status) # 404
print(err.code) # stable machine-readable code
print(err.request_id) # quote this to supportPagination
List endpoints return a { data, pagination } envelope. Pass pagination.next_cursor back as the cursor parameter to fetch the next page — see Pagination for the full model.
Next steps
- API reference — every endpoint, parameter, and response shape.
- Connect an ESP — verify-first automation across 18 email platforms.
- Webhooks — get notified instead of polling.