@canitsend/client
v1.0.0
Published
Client for the CanItSend API — SPF/DKIM/DMARC audit from live DNS, SPF flattening, and email validation.
Downloads
146
Maintainers
Readme
@canitsend/client
Zero-dependency client for the CanItSend API. Two questions, one API.
npm install @canitsend/clientEvery endpoint needs an API key. The free tier includes 100 audits/month — instant, self-serve, no sales call: https://canitsend.com/#pricing
import { CanItSendClient } from "@canitsend/client";
const cis = new CanItSendClient({ apiKey: process.env.CANITSEND_KEY });1. Can my domain send?
const a = await cis.check("acme.com"); // also accepts "[email protected]" or a URL
console.log(a.grade, a.score); // "F" 40
// Plain-language answer to "but my email works!"
console.log(a.explanation?.headline);
// → "Your mail works — but you can't prove you sent it."
// The exact records to paste, chosen for YOUR detected mail provider
for (const r of a.suggestedRecords) console.log(r.type, r.host, r.value);
// → TXT @ v=spf1 include:_spf.google.com ~all
// → TXT _dmarc v=DMARC1; p=none; rua=mailto:[email protected]The SPF 10-lookup limit
Over 10 DNS lookups means PermError — SPF fails entirely, not partially.
We count it correctly: mx costs 1, not one per MX host. Most tools get this wrong.
const spf = await cis.spfCheck("acme.com");
console.log(spf.lookupCount, "/ 10", spf.lookupLimitExceeded ? "PermError!" : "");
// Fix it: resolve every include: down to raw IPs (which cost 0 lookups)
const { flattened } = await cis.spfFlatten("acme.com");2. Should I send to this address?
const v = await cis.validate("[email protected]");
console.log(v.verdict); // "risky"
console.log(v.didYouMean); // "[email protected]"
await cis.validate("[email protected]"); // risky — disposable
await cis.validate("[email protected]"); // risky — role account
await cis.validate("[email protected]"); // invalid — no MX, will bounceWhat we don't claim: we do not verify the mailbox exists and do not detect catch-alls. Both need an SMTP probe on port 25, which we deliberately don't run.
mailboxVerifiedis alwaysfalse. The strongest verdict isdeliverable_domain— meaning the domain accepts mail.
Bulk (Agency+): auditBulk([...]) up to 100 domains · validateBulk([...]) up to 1,000 addresses.
Monitoring
await cis.createMonitor("acme.com", { webhookUrl: "https://you/hook", frequency: "daily" });
// We re-audit on a schedule and POST your webhook when the posture regresses.Errors throw CanItSendError with .status and .problem (RFC 9457 problem+json).
