You built a journaling app, a habit tracker, or a mood log. Users type their thoughts. Then... nothing. The text sits there.
What if your app could detect when a user is spiraling into all-or-nothing thinking, catastrophizing, or self-blame — and gently offer a reframe? That's a mental health check-in, and it's the difference between a diary and a tool that actually helps.
I open-sourced a Cognitive Behavioral Therapy (CBT) thought analyzer that detects 10 cognitive distortions from text. It's free, no API key needed, and works in 3 lines of code.
The 3 lines (JavaScript)
const res = await fetch('https://cbt-thought-analyzer.onrender.com/analyze', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({text: userInput})
});
const {distortions} = await res.json();
That's it. distortions is an array of detected cognitive distortions, each with a name, description, confidence, matched patterns, and a CBT-based reframe.
What you get back
Send this thought:
"I always mess everything up. Nothing ever goes right for me. I'm a total failure."
You get back:
{
"distortions": [
{
"name": "All-or-Nothing Thinking",
"description": "You see things in black-and-white. If it's not perfect, it's a total failure.",
"confidence": "medium",
"matched_patterns": ["always", "total failure"],
"reframe": "Is there a middle ground? What counts as 'good enough' here? One mistake doesn't cancel everything else that went well."
},
{
"name": "Overgeneralization",
"description": "You treat one negative event as a never-ending pattern of defeat.",
"confidence": "medium",
"matched_patterns": ["always", "nothing ever"],
"reframe": "What's the evidence for 'always'? Can you name one time things DID go right?"
}
]
}
Now your UI can show the reframe inline, log it for the user's review, or trigger a gentle check-in prompt.
The 10 distortions it detects
These are the classic Aaron Beck cognitive distortions — the same ones therapists look for:
- All-or-Nothing Thinking — black-and-white, "if it's not perfect it's a failure"
- Overgeneralization — "always" / "never" patterns from one event
- Mental Filter — dwelling on one negative, ignoring positives
- Jumping to Conclusions — mind-reading or fortune-telling
- Catastrophizing — "what if everything goes wrong"
- Personalization — blaming yourself for things outside your control
- Should Statements — rigid "I should" / "I must" demands
- Labeling — "I'm a loser" instead of "I made a mistake"
- Emotional Reasoning — "I feel it, so it must be true"
- Disqualifying the Positive — "that doesn't count"
Each comes with a reframe — a CBT-based question that helps the user challenge the distortion. This is the active ingredient of CBT, not just labeling.
Python version
import requests
res = requests.post('https://cbt-thought-analyzer.onrender.com/analyze',
json={'text': user_input})
distortions = res.json()['distortions']
for d in distortions:
print(f"{d['name']}: {d['reframe']}")
curl
curl -X POST https://cbt-thought-analyzer.onrender.com/analyze -H "Content-Type: application/json" -d '{"text":"I should have done better. I always fail."}'
A real integration example
Here's how you'd wire it into a journaling app's submit handler:
async function handleJournalSubmit(text) {
// Save the entry
await saveEntry(text);
// Analyze for cognitive distortions
const res = await fetch('https://cbt-thought-analyzer.onrender.com/analyze', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({text})
});
const {distortions} = await res.json();
// If we detect distortions, offer a gentle reframe
if (distortions.length > 0) {
showReframePrompt(distortions[0]);
// distortions[0].reframe is the CBT question to show the user
}
}
function showReframePrompt(distortion) {
// Non-intrusive: a card below the entry, not a modal
renderCard({
title: `Noticed: ${distortion.name}`,
body: distortion.reframe,
actions: ['Reflect', 'Dismiss']
});
}
The key UX principle: don't interrupt, augment. Show the reframe as a card below the entry, not a popup. The user is writing, not being diagnosed.
Why this is free
The API runs on Render's free tier. It's a single FastAPI service hosting three CBT analyzers (thought distortions, procrastination patterns, attachment style). Source code is on GitHub under MIT.
If you need higher reliability or rate limits, the same analyzers are available on RapidAPI (search "CBT Thought Analyzer"). Same logic, RapidAPI handles the infra.
What this is NOT
- Not a diagnosis. Cognitive distortions are thought patterns, not symptoms. Detecting "all-or-nothing thinking" doesn't mean the user has a disorder.
- Not therapy. CBT with a therapist is the gold standard. This is a nudge, not treatment.
- Not a replacement for crisis resources. If your app handles mental health, include crisis line links. The API returns distortions; it doesn't assess risk.
The bigger picture
Most "mental health features" in apps are mood trackers — a 1-5 emoji picker. That's a log, not a tool. The difference between a log and a tool is whether the app does something with the data.
Detecting cognitive distortions turns a passive mood log into an active CBT exercise. The user writes a thought, the app identifies the distortion, and offers the reframe. That loop — identify → challenge → reframe — is the core of CBT. You're not building a mood tracker, you're building a thought-record tool.
The cbt-toolkit repo has 36 standalone HTML tools covering specific distortions (OCD, social anxiety, perfectionism, procrastination, etc.) if you want to go deeper. The API is the programmatic version of those.
Repo: github.com/alexcoledev/cbt-toolkit
API: https://cbt-thought-analyzer.onrender.com/analyze (POST, JSON)
License: MIT
Cost: Free, no API key needed for the hosted endpoint
If you integrate this, I'd love to see what you build. Drop a comment or open a Discussion on the repo.
Top comments (0)