A web service that receives emails via HTTP and scans them with one or many filtering engines (antivirus, antispam, policy engines, etc.)
- fprot
- f-secure
- eset
- kaspersky
- comodo
- dspam
- messagesniffer
- avg
Send the raw message as the HTTP request body.
curl -X POST --data-binary @test/files/eicar.eml localhost:8000/scanSMTP envelope and upstream authentication results travel as X-Env-* request
headers — the message body can't supply them. Engines use what they need (DCC
builds its dccifd envelope from IP/Helo/From/Rcpt; rspamd receives the
full set as its native headers) and ignore the rest. Repeat X-Env-Rcpt for
multiple recipients.
curl -X POST --data-binary @test/files/eicar.eml \
-H 'X-Env-IP: 203.0.113.7' \
-H 'X-Env-Helo: mail.example.com' \
-H 'X-Env-From: sender@example.com' \
-H 'X-Env-Rcpt: rcpt@example.net' \
-H 'X-Env-SPF: pass' \
localhost:8000/scanAny X-Env-* header is forwarded to rspamd verbatim (e.g. X-Env-User,
X-Env-Hostname, X-Env-Queue-Id, X-Env-TLS-Cipher, X-Env-TLS-Version).
X-Env-SPF is captured for DMARC evaluation (not yet implemented).
The response is a JSON array with one entry per available scanner. Each entry
reports pass, fail, and error lists alongside the engine's raw output;
a non-empty fail means that engine flagged the message.
The example below is a real scan of the bundled EICAR test message, with raw
trimmed for brevity.
[
{
"name": "clamav",
"pass": [],
"fail": ["Eicar-Signature"],
"error": [],
"raw": "stream: Eicar-Signature FOUND"
},
{
"name": "virustotal",
"pass": [],
"fail": [41],
"error": []
},
{
"name": "spamassassin",
"pass": ["ham"],
"fail": [],
"error": []
},
{
"name": "rspamd",
"pass": [],
"fail": [8.5],
"error": []
},
{
"name": "dcc",
"pass": ["A"],
"fail": [],
"error": [],
"raw": "A\nA\nX-DCC-...; bulk rep Body=3 Fuz1=3 Fuz2=3 rep=23%\n\n"
},
{
"name": "opendkim",
"pass": [],
"fail": ["message not signed"],
"error": []
}
]The daemon serves a small web UI (Home, Status, Scan) on the configured listen port, backed by two JSON endpoints:
GET /status/scannersAll— every known scannerGET /status/scannersAvailable— scanners currently reachable, and the interface (cli,socket, ornetwork) each was detected on