@safenest/sdk
Official TypeScript/JavaScript SDK for the SafeNest API
AI-powered child safety analysis for modern applications
Documentation •
Dashboard •
Discord •
Twitter
Overview
SafeNest provides AI-powered content analysis to help protect children in digital environments. This SDK makes it easy to integrate SafeNest's capabilities into your Node.js, browser, or edge runtime applications.
Key Features
- Bullying Detection — Identify verbal abuse, exclusion, and harassment patterns
- Grooming Risk Analysis — Detect predatory behavior across conversation threads
- Unsafe Content Detection — Flag self-harm, violence, hate speech, and age-inappropriate content
- Emotional State Analysis — Understand emotional signals and concerning trends
- Action Guidance — Generate age-appropriate response recommendations
- Incident Reports — Create professional summaries for review
Why SafeNest?
| Privacy-First | Stateless analysis, no mandatory data storage |
| Human-in-the-Loop | Designed to assist, not replace, human judgment |
| Clear Rationale | Every decision includes explainable reasoning |
| Safe Defaults | Conservative escalation, no automated responses to children |
Installation
npm install @safenest/sdk
yarn add @safenest/sdk
pnpm add @safenest/sdk
bun add @safenest/sdk
Requirements
- Node.js 18+ (or any runtime with
fetch support)
- TypeScript 4.7+ (optional, for type definitions)
Quick Start
import { SafeNest } from '@safenest/sdk'
const safenest = new SafeNest(process.env.SAFENEST_API_KEY)
const result = await safenest.analyze("User message to analyze")
if (result.risk_level !== 'safe') {
console.log('Risk detected:', result.risk_level)
console.log('Summary:', result.summary)
console.log('Action:', result.recommended_action)
}
API Reference
Initialization
import { SafeNest } from '@safenest/sdk'
const safenest = new SafeNest('your-api-key')
const safenest = new SafeNest('your-api-key', {
timeout: 30000,
retries: 3,
retryDelay: 1000,
})
Tracking Fields
All detection methods accept optional tracking fields for correlation, multi-tenant routing, and custom metadata:
const result = await safenest.detectBullying({
content: "Nobody likes you, just leave",
context: 'chat',
external_id: 'msg_abc123',
customer_id: 'cust_xyz789',
metadata: { channel: 'discord' }
})
console.log(result.external_id)
console.log(result.customer_id)
console.log(result.metadata)
external_id | string? | 255 | Your internal identifier (message ID, content ID, etc.) |
customer_id | string? | 255 | Your end-customer identifier for multi-tenant / B2B2C scenarios |
metadata | object? | — | Custom key-value pairs stored with the detection result |
These fields are:
- Echoed in the API response for easy matching
- Included in webhook payloads, enabling you to route alerts to the correct customer from a single webhook endpoint
- Stored with the incident in Firestore for audit trail
Safety Detection
detectBullying(input)
Detects bullying and harassment in text content.
const result = await safenest.detectBullying({
content: "Nobody likes you, just leave",
context: 'chat'
})
console.log(result.is_bullying)
console.log(result.severity)
console.log(result.bullying_type)
console.log(result.confidence)
console.log(result.risk_score)
console.log(result.rationale)
console.log(result.recommended_action)
detectGrooming(input)
Analyzes conversation threads for grooming patterns.
const result = await safenest.detectGrooming({
messages: [
{ role: 'adult', content: "This is our special secret" },
{ role: 'child', content: "Ok I won't tell anyone" }
],
childAge: 12
})
console.log(result.grooming_risk)
console.log(result.flags)
console.log(result.confidence)
console.log(result.risk_score)
console.log(result.rationale)
console.log(result.recommended_action)
detectUnsafe(input)
Identifies potentially dangerous or harmful content.
const result = await safenest.detectUnsafe({
content: "I don't want to be here anymore"
})
console.log(result.unsafe)
console.log(result.categories)
console.log(result.severity)
console.log(result.risk_score)
console.log(result.rationale)
console.log(result.recommended_action)
analyze(content)
Quick combined analysis — runs bullying and unsafe detection in parallel.
Note: This method fires one API call per detection type included (default: 2 calls for bullying + unsafe). Each call counts against your monthly quota. Use include to run only the checks you need.
const result = await safenest.analyze("Message to check")
const result = await safenest.analyze({
content: "Message to check",
context: 'social_media',
include: ['bullying', 'unsafe']
})
console.log(result.risk_level)
console.log(result.risk_score)
console.log(result.summary)
console.log(result.bullying)
console.log(result.unsafe)
console.log(result.recommended_action)
Emotional Analysis
analyzeEmotions(input)
Summarizes emotional signals in content or conversations.
const result = await safenest.analyzeEmotions({
content: "I'm so stressed about everything lately"
})
const result = await safenest.analyzeEmotions({
messages: [
{ sender: 'child', content: "I failed the test" },
{ sender: 'child', content: "Everyone else did fine" },
{ sender: 'child', content: "I'm so stupid" }
]
})
console.log(result.dominant_emotions)
console.log(result.emotion_scores)
console.log(result.trend)
console.log(result.summary)
console.log(result.recommended_followup)
Guidance & Reports
getActionPlan(input)
Generates age-appropriate action guidance.
const plan = await safenest.getActionPlan({
situation: 'Someone is spreading rumors about me at school',
childAge: 12,
audience: 'child',
severity: 'medium'
})
console.log(plan.audience)
console.log(plan.steps)
console.log(plan.tone)
console.log(plan.reading_level)
generateReport(input)
Creates structured incident summaries for professional review.
const report = await safenest.generateReport({
messages: [
{ sender: 'user1', content: 'Threatening message' },
{ sender: 'child', content: 'Please stop' }
],
childAge: 14,
incident: {
type: 'harassment',
occurredAt: new Date()
}
})
console.log(report.summary)
console.log(report.risk_level)
console.log(report.categories)
console.log(report.recommended_next_steps)
Policy Configuration
getPolicy() / setPolicy(config)
Customize safety thresholds for your application.
const policy = await safenest.getPolicy()
await safenest.setPolicy({
bullying: {
enabled: true,
minRiskScoreToFlag: 0.5,
minRiskScoreToBlock: 0.8
},
selfHarm: {
enabled: true,
alwaysEscalate: true
}
})
Account Management (GDPR)
deleteAccountData()
Permanently delete all data associated with your account (Right to Erasure, GDPR Article 17).
const result = await safenest.deleteAccountData()
console.log(result.message)
console.log(result.deleted_count)
exportAccountData()
Export all data associated with your account as JSON (Right to Data Portability, GDPR Article 20).
const data = await safenest.exportAccountData()
console.log(data.userId)
console.log(data.exportedAt)
console.log(Object.keys(data.data))
console.log(data.data.incidents.length)
Usage Tracking
The SDK automatically captures usage metadata from API responses:
const result = await safenest.detectBullying({ content: 'test' })
console.log(safenest.usage)
console.log(safenest.lastRequestId)
console.log(safenest.lastLatencyMs)
Error Handling
The SDK provides typed error classes for different failure scenarios:
import {
SafeNest,
SafeNestError,
AuthenticationError,
RateLimitError,
QuotaExceededError,
TierAccessError,
ValidationError,
NotFoundError,
ServerError,
TimeoutError,
NetworkError,
} from '@safenest/sdk'
try {
const result = await safenest.detectBullying({ content: 'test' })
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Check your API key')
} else if (error instanceof TierAccessError) {
console.error('Upgrade your plan:', error.suggestion)
} else if (error instanceof QuotaExceededError) {
console.error('Quota exceeded, upgrade or buy credits')
} else if (error instanceof RateLimitError) {
console.error('Rate limited, retry after:', error.retryAfter)
} else if (error instanceof ValidationError) {
console.error('Invalid input:', error.details)
} else if (error instanceof NotFoundError) {
console.error('Resource not found')
} else if (error instanceof ServerError) {
console.error('Server error, try again later')
} else if (error instanceof TimeoutError) {
console.error('Request timed out')
} else if (error instanceof NetworkError) {
console.error('Check your connection')
} else if (error instanceof SafeNestError) {
console.error('Error:', error.message)
}
}
TypeScript Support
Full TypeScript support with comprehensive type definitions:
import { SafeNest } from '@safenest/sdk'
import type {
BullyingResult,
GroomingResult,
UnsafeResult,
EmotionsResult,
ActionPlanResult,
ReportResult,
AnalyzeResult,
DetectBullyingInput,
DetectGroomingInput,
DetectUnsafeInput,
AnalyzeEmotionsInput,
GetActionPlanInput,
GenerateReportInput,
AccountDeletionResult,
AccountExportResult,
Usage,
ContextInput,
GroomingMessage,
EmotionMessage,
ReportMessage,
} from '@safenest/sdk'
Using Enums
The SDK exports enums for type-safe comparisons:
import {
Severity,
GroomingRisk,
RiskLevel,
RiskCategory,
AnalysisType,
EmotionTrend,
IncidentStatus,
ErrorCode,
} from '@safenest/sdk'
if (result.severity === Severity.CRITICAL) {
}
if (result.grooming_risk === GroomingRisk.HIGH) {
}
if (error.code === ErrorCode.RATE_LIMIT_EXCEEDED) {
}
You can also import enums separately:
import { Severity, RiskCategory } from '@safenest/sdk/constants'
Examples
Next.js Integration (App Router)
Use a server-side API route to keep your API key secure:
import { SafeNest } from '@safenest/sdk'
import { NextResponse } from 'next/server'
const safenest = new SafeNest(process.env.SAFENEST_API_KEY!)
export async function POST(req: Request) {
const { message } = await req.json()
const result = await safenest.analyze(message)
return NextResponse.json(result)
}
'use client'
import { useState } from 'react'
function MessageInput() {
const [message, setMessage] = useState('')
const [warning, setWarning] = useState<string | null>(null)
const handleSubmit = async () => {
const res = await fetch('/api/safety', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message }),
})
const result = await res.json()
if (result.risk_level !== 'safe') {
setWarning(result.summary)
return
}
}
return (
<div>
<input value={message} onChange={e => setMessage(e.target.value)} />
{warning && <p className="warning">{warning}</p>}
<button onClick={handleSubmit}>Send</button>
</div>
)
}
Express Middleware
import { SafeNest, RateLimitError } from '@safenest/sdk'
import express from 'express'
const safenest = new SafeNest(process.env.SAFENEST_API_KEY)
const safetyMiddleware = async (req, res, next) => {
const { message } = req.body
try {
const result = await safenest.analyze(message)
if (result.risk_level === 'critical') {
return res.status(400).json({
error: 'Message blocked for safety reasons',
details: result.summary
})
}
req.safetyResult = result
next()
} catch (error) {
if (error instanceof RateLimitError) {
return res.status(429).json({ error: 'Too many requests' })
}
next(error)
}
}
app.post('/messages', safetyMiddleware, (req, res) => {
})
Batch Processing
const messages = ['message1', 'message2', 'message3']
const results = await Promise.all(
messages.map(content => safenest.analyze(content))
)
const flagged = results.filter(r => r.risk_level !== 'safe')
console.log(`${flagged.length} messages flagged for review`)
Browser Support
The SDK works in browsers that support the Fetch API:
<script type="module">
import { SafeNest } from 'https://esm.sh/@safenest/sdk'
const safenest = new SafeNest('your-api-key')
const result = await safenest.analyze('Hello world')
</script>
Note: Never expose your API key in client-side code for production applications. Use a backend proxy to protect your credentials.
Contributing
We welcome contributions! Please see our Contributing Guide for details.
git clone https://github.com/SafeNestSDK/node.git
cd node
npm install
npm test
npm run build
API Documentation
Rate Limits
Rate limits depend on your subscription tier:
| Starter | Free | 1,000 | 60/min | 3 Safety endpoints, 1 API key, Community support |
| Indie | $29/mo | 10,000 | 300/min | All 7 endpoints, 2 API keys, Dashboard analytics |
| Pro | $99/mo | 50,000 | 1,000/min | 5 API keys, Webhooks, Custom policy, Priority latency |
| Business | $349/mo | 200,000 | 5,000/min | 20 API keys, SSO, SLA 99.9%, HIPAA/SOC2 docs |
| Enterprise | Custom | Unlimited | Custom | Dedicated infra, 24/7 support, SCIM, On-premise |
Credit Packs (available to all tiers): 5K calls/$15 | 25K calls/$59 | 100K calls/$199
Best Practices
Message Batching
The bullying and unsafe content methods analyze a single text field per request. If your platform receives messages one at a time (e.g., a chat app), concatenate a sliding window of recent messages into one string before calling the API. Single words or short fragments lack context for accurate detection and can be exploited to bypass safety filters.
for (const msg of messages) {
await client.detectBullying({ content: msg });
}
const window = recentMessages.slice(-10).join(' ');
await client.detectBullying({ content: window });
The grooming method already accepts a messages[] array and analyzes the full conversation in context.
PII Redaction
PII redaction is enabled by default on the SafeNest API. It automatically strips emails, phone numbers, URLs, social handles, IPs, and other PII from detection summaries and webhook payloads. The original text is still analyzed in full — only stored outputs are scrubbed. Set PII_REDACTION_ENABLED=false to disable.
Support
License
MIT License - see LICENSE for details.
Built with care for child safety by the SafeNest team