Skip to content
jeff.safety.spamv1.4.0

Spam and phishing detection

Detects spam or phishing in text messages and emails. A separate function classifies each message as legitimate, spam or phishing.

Open in playground

Example

Context

channel
sms

Input

Your parcel could not be delivered. Pay the 1.99 redelivery fee within 24 hours here: http://parcel-redeliver.example/pay

Answer (JSON)
value phishing, confidence 0.911
Top options
  1. phishing 0.911
  2. spam 0.088
  3. legitimate 0.001

A message asking for a small fee through an unknown link is after money or details, so it is phishing.

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.spam.message_type", context={        "channel": "sms",    })     decision = decide("Your parcel could not be delivered. Pay the 1.99 redelivery fee within 24 hours here: http://parcel-redeliver.example/pay")     print(decision.value, decision.confidence)

More examples

  • Dentist's appointment reminderanswer legitimate · confidence 1

    Context

    channel
    sms

    Input

    Hi Jo, a reminder of your appointment at Riverside Dental on Thursday 12 November at 9:15. Reply C to cancel. See you then!

    Answer (JSON)
    value legitimate, confidence 1
    Top options
    1. legitimate 1
    2. phishing 0
    3. spam 0

    A dental practice reminds a patient of a booked appointment, so the message is legitimate.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.spam.message_type", context={        "channel": "sms",    })     decision = decide("Hi Jo, a reminder of your appointment at Riverside Dental on Thursday 12 November at 9:15. Reply C to cancel. See you then!")     print(decision.value, decision.confidence)
  • Mass-mailed sofa saleanswer spam · confidence 0.916

    Context

    channel
    email

    Input

    Subject: MEGA SOFA SALE - 70% OFF EVERYTHING THIS WEEKEND ONLY! Dear customer, our biggest sale ever starts now. Corner sofas from 299, free delivery, 0% finance. Shop now before stock runs out! To unsubscribe click here.

    Answer (JSON)
    value spam, confidence 0.916
    Top options
    1. spam 0.916
    2. phishing 0.083
    3. legitimate 0.001

    A mass-mailed sale with an unsubscribe link is unwanted advertising, so it is spam.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.spam.message_type", context={        "channel": "email",    })     decision = decide("Subject: MEGA SOFA SALE - 70% OFF EVERYTHING THIS WEEKEND ONLY! Dear customer, our biggest sale ever starts now. Corner sofas from 299, free delivery, 0% finance. Shop now before stock runs out! To unsubscribe click here.")     print(decision.value, decision.confidence)
  • Prize text asking for bank detailsanswer true · confidence 1

    Context

    channel
    sms

    Input

    CONGRATULATIONS! You have won a 500 shopping voucher. To claim, reply with your full name, date of birth and bank card number within 2 hours.

    Answer (JSON)
    value true, confidence 1
    Top options
    1. true 1
    2. false 0

    A prize text asking for a bank card number is a scam, so the answer to whether it is spam or phishing is true.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.spam.is_spam", context={        "channel": "sms",    })     decision = decide("CONGRATULATIONS! You have won a 500 shopping voucher. To claim, reply with your full name, date of birth and bank card number within 2 hours.")     print(decision.value, decision.confidence)
  • A colleague moving a meetinganswer false · confidence 1

    Context

    channel
    email

    Input

    Subject: Moving our Thursday catch-up. Hi Dan, could we move Thursday's catch-up to 2 pm? I have a client call at 11 now. Thanks, Meera

    Answer (JSON)
    value false, confidence 1
    Top options
    1. false 1
    2. true 0

    A colleague asks to move a meeting, a normal message, so the answer is false.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.spam.is_spam", context={        "channel": "email",    })     decision = decide("Subject: Moving our Thursday catch-up. Hi Dan, could we move Thursday's catch-up to 2 pm? I have a client call at 11 now. Thanks, Meera")     print(decision.value, decision.confidence)

Use when

  • You need spam and phishing probabilities for incoming text messages or emails.
  • You need to distinguish advertising spam from scams seeking personal details, passwords or money.

Avoid when

  • You need to inspect email headers, links or attachments; this adapter reads only the subject and readable body.
  • You need a definitive blocking decision without human review; use the prediction as one input to that decision.

Context and input

FieldKindDescription
message
inputThe text of the message as received. For an email, its subject and readable body (no other headers, no attachments).
channel
contextWhere the message came from: "sms" or "email", as in training.

Functions

KeyInterfaceInstructionsLabels
is_spamdetectIs this message spam or phishing? Answer yes if it is unwanted bulk or advertising, or a scam trying to get personal details or money; answer no if it is a normal message.false, true
message_typeclassifyWhat kind of message is this: a legitimate message, spam (unwanted bulk or advertising), or phishing (a scam trying to get personal details, passwords or money)?legitimate, phishing, spam

How it was measured

Test accuracy: the share of test rows whose top answer was right.

  • 98.4% on real messages from public spam and phishing collections (SMS and email) (3,897 rows). public benchmark
  • 98.3% on the test set of the earlier version (3,603 rows). public benchmark

When confident

From the calibration set: at or above the threshold confidence, how often the answer is right, and how often the adapter is that confident. Below it, escalate.

FunctionRight when confidentConfident onThresholdCalibration rows
is_spam99.2%100.0%0.521,113
message_type98.1%100.0%0.43832

Base: Jeff v1.4. Adapter trained: 25 October 2026.

Base

jeff-base v1.4

Call it

jeff.safety.spam.is_spam, with placeholders for its input and context.

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.safety.spam.is_spam", context={        "channel": "<channel>",    })     decision = decide("<message>")     print(decision.value, decision.confidence)

Download

Weights: mstrasser/jeff-adapter-spam (v1.4)

Licence: Apache-2.0