Supported MTA · KumoMTA
BigStats consumes KumoMTA's JSON log records through a standard HTTP log hook and turns reception, delivery, deferral and bounce traffic into deliverability reporting your team can act on — plus configurable CSV and JSON exports of the exact fields you need.
KumoMTA log record → BigStats
POST https://bigstats.email/api/public/ingest/kumomta?key=ga_live_…
{"type":"Bounce","recipient":"user@gmail.com","egress_pool":"pool_a",
"source_address":{"address":"198.51.100.7"},
"response":{"code":550,"enhanced_code":{"class":5,"subject":1,"detail":1},
"content":"5.1.1 user unknown"}}
→ classified: hard · invalid_recipient · isp=gmailRecord coverage
Every accepted message and successful delivery, with egress pool, egress source IP, peer MTA and the receiving server's SMTP response.
Deferrals with the full response text and enhanced status code, so throttling by a mailbox provider shows up long before it turns into a bounce wave.
SMTP reply code, enhanced status code and response content parsed into hard/soft/block plus a category — invalid recipient, mailbox full, blocklisted, throttled, policy, authentication or network.
Out-of-band bounces and feedback-loop complaints tracked as first-class rates, per ISP and per sending IP.
Messages refused at reception, kept separate from post-acceptance failures so injection problems are not confused with delivery problems.
Connect it
01
Each BigStats workspace issues its own ingest key and KumoMTA endpoint. Nothing else in your sending stack changes.
02
Configure a log hook in your KumoMTA policy that posts JSON log records to the BigStats endpoint with your key attached.
03
Records are normalized and queryable immediately — no batch window — and rollups keep reports fast at production volume.
init.lua
kumo.on('init', function()
kumo.configure_log_hook {
name = 'bigstats',
headers = { 'Subject', 'X-Campaign-Id', 'X-Mailing-Id' },
}
end)
kumo.on('make.bigstats', function(domain, tenant, campaign)
local sender = {}
function sender:send(message)
local response = kumo.http.build_client({})
:post('https://bigstats.email/api/public/ingest/kumomta')
:header('X-BigStats-Key', '<INGEST_KEY>')
:header('Content-Type', 'application/json')
:body(message:get_data())
:send()
if not response:status_is_success() then
kumo.reject(500, 'bigstats: ' .. response:text())
end
return response:text()
end
return sender
end)Received, delivered, deferred and bounced with period-over-period deltas and a composite health score.
Gmail, Microsoft, Yahoo, Apple and corporate buckets with delivery, bounce and complaint rates side by side.
Hard/soft/block split, category classification and per-source-IP bounce pressure with sample responses.
FAQ
Reception, Delivery, Bounce, TransientFailure, Expiration, AdminBounce, OOB, Feedback and Rejection. Each record's SMTP reply code, enhanced status code and response content are retained alongside the normalized classification.
No. BigStats only receives log records through a log hook. It never touches queues, egress sources, shaping or message content, and a delivery failure to BigStats does not affect outbound mail once the hook queue is configured normally.
Yes. Egress pool, egress source address and peer MTA are captured on every record, so you can compare bounce and deferral pressure across the IP pool, spot senders sharing an IP and isolate a warming source that is hurting placement.
KumoMTA does not generate open or click events itself, so those streams stay empty unless another system in your stack posts them to the same workspace. Everything else — deliveries, deferrals, bounces, complaints and rejections — is fully reported.
Include the headers you care about — Subject, X-Campaign-Id, X-Mailing-Id — in the log hook configuration. BigStats maps them onto subject, campaign and mailing fields so reports and exports can be grouped by them.