Spam and phishing detection
Detects spam or phishing in text messages and emails. A separate function classifies each message as legitimate, spam or phishing.
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
- phishing 0.911
- spam 0.088
- legitimate 0.001
A message asking for a small fee through an unknown link is after money or details, so it is phishing.
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
- legitimate 1
- phishing 0
- spam 0
A dental practice reminds a patient of a booked appointment, so the message is
legitimate.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
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
- spam 0.916
- phishing 0.083
- legitimate 0.001
A mass-mailed sale with an unsubscribe link is unwanted advertising, so it is
spam.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
- true 1
- 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.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
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
- false 1
- true 0
A colleague asks to move a meeting, a normal message, so the answer is
false.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
| Field | Kind | Description |
|---|---|---|
message | input | The text of the message as received. For an email, its subject and readable body (no other headers, no attachments). |
channel | context | Where the message came from: "sms" or "email", as in training. |
Functions
| Key | Interface | Instructions | Labels |
|---|---|---|---|
| is_spam | detect | Is 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_type | classify | What 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.
| Function | Right when confident | Confident on | Threshold | Calibration rows |
|---|---|---|---|---|
| is_spam | 99.2% | 100.0% | 0.52 | 1,113 |
| message_type | 98.1% | 100.0% | 0.43 | 832 |
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