API

Check an email from your app.

View Markdown

Send the raw email to POST /v1/check. The answer is a stream of JSON lines, one per check, sent as each check finishes. A verdict line arrives with the first check that decides, and again whenever a later check changes the verdict. The last line, done, has the final verdict.

Usage

curl -sN --data-binary @message.eml "$MAILWEFT_API/v1/check?llm=off"

Read the stream line by line in JavaScript:

const response = await fetch(`${api}/v1/check?llm=auto`, { method: 'POST', body: raw });const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();let buffer = '';for (;;) {  const { value, done } = await reader.read();  if (done) break;  buffer += value;  const lines = buffer.split('\n');  buffer = lines.pop();  for (const line of lines.filter(Boolean)) {    const event = JSON.parse(line);    if (event.event === 'verdict') show(event.verdict, event.reason); // first answer, then any change    if (event.event === 'done') finish(event.verdict);  }}

Request

PartValue
BodyThe raw email, with headers. At most 1 MB.
llmauto (default) runs the judge when needed. always runs it on every email. off never runs it.

The judge may run 30 times an hour for each address. Only runs count; a check where the judge is not needed does not. After that the judge is skipped and the judge line says why.

Events

Events arrive in this order. A verdict event can appear after any check that changes the verdict.

EventFields
parsedsubject, from, chars, auth (SPF, DKIM and DMARC results), links
rulesflag, claimed (organisations the email claims to be), reasons
b2score, logit, model_ms
b3score, band, model, flag_at, safe_below, raises, lowers
memorymatches, each with level, class, harmful, score, date, source, start and campaign; unavailable when the server has no memory
b2_sentencessentences, each with the text and the score drop when it is removed
judgeran, verdict, confidence, reason, quotes, quotes_verified, model_ms, or skipped with the reason
verdictverdict (phishing, unsure or safe), by (the check that decided), reason, first
doneThe final verdict

Every event except error has ms, the time since the request arrived on the server.

Errors

StatusMessage
400Empty email. Paste an email or open a sample.
413Email is larger than 1 MB. Remove attachments and try again.

An error during a check arrives as an error event in the stream.

Health

GET /v1/health returns the loaded models, the number of memory entries, and whether the judge is configured.