Express Integration
Add content moderation to your Express API in minutes.
Installation
bash
npm install @nextauralabs/vettly-sdkQuick Start
Basic Usage
js
const express = require('express')
const { ModerationClient } = require('@nextauralabs/vettly-sdk')
const app = express()
app.use(express.json())
const vettly = new ModerationClient({
apiKey: process.env.VETTLY_API_KEY
})
app.post('/api/comments', async (req, res) => {
const { content } = req.body
const result = await vettly.check({
content,
contentType: 'text'
})
if (result.action === 'block') {
return res.status(403).json({
error: 'Content blocked',
categories: result.categories
})
}
// Save comment to database
res.json({ success: true })
})
app.listen(3000)Middleware Pattern
js
const { ModerationClient } = require('@nextauralabs/vettly-sdk')
const vettly = new ModerationClient({
apiKey: process.env.VETTLY_API_KEY
})
// Reusable moderation middleware
function moderate(field = 'content') {
return async (req, res, next) => {
const content = req.body[field]
if (!content) {
return next()
}
try {
const result = await vettly.check({
content,
contentType: 'text'
})
req.moderation = result
if (result.action === 'block') {
return res.status(403).json({
error: 'Content blocked by moderation policy'
})
}
next()
} catch (error) {
console.error('Moderation error:', error)
next() // Fail open
}
}
}
// Use on specific routes
app.post('/api/comments', moderate('content'), (req, res) => {
// req.moderation contains the result
res.json({ success: true })
})
app.post('/api/posts', moderate('body'), (req, res) => {
res.json({ success: true })
})TypeScript Version
ts
import express, { Request, Response, NextFunction } from 'express'
import { ModerationClient, ModerationResult } from '@nextauralabs/vettly-sdk'
const app = express()
app.use(express.json())
const vettly = new ModerationClient({
apiKey: process.env.VETTLY_API_KEY!
})
// Extend Request type
declare global {
namespace Express {
interface Request {
moderation?: ModerationResult
}
}
}
function moderate(field: string = 'content') {
return async (req: Request, res: Response, next: NextFunction) => {
const content = req.body[field]
if (!content) return next()
const result = await vettly.check({
content,
contentType: 'text'
})
req.moderation = result
if (result.action === 'block') {
return res.status(403).json({ error: 'Content blocked' })
}
next()
}
}
app.post('/api/comments', moderate(), (req, res) => {
console.log('Moderation result:', req.moderation)
res.json({ success: true })
})Image Moderation
js
const multer = require('multer')
const upload = multer({ storage: multer.memoryStorage() })
app.post('/api/upload', upload.single('image'), async (req, res) => {
const base64 = req.file.buffer.toString('base64')
const result = await vettly.check({
content: base64,
contentType: 'image'
})
if (result.action === 'block') {
return res.status(403).json({
error: 'Image contains inappropriate content'
})
}
// Process upload
res.json({ success: true })
})Multiple Fields
js
app.post('/api/posts', async (req, res) => {
const { title, body } = req.body
// Check both fields
const [titleResult, bodyResult] = await Promise.all([
vettly.check({ content: title, contentType: 'text' }),
vettly.check({ content: body, contentType: 'text' })
])
if (titleResult.action === 'block' || bodyResult.action === 'block') {
return res.status(403).json({ error: 'Content blocked' })
}
res.json({ success: true })
})Error Handling
js
app.post('/api/comments', async (req, res) => {
try {
const result = await vettly.check({
content: req.body.content,
contentType: 'text'
})
if (result.action === 'block') {
return res.status(403).json({ error: 'Blocked' })
}
res.json({ success: true })
} catch (error) {
console.error('Moderation failed:', error)
// Decide: block all or allow all on error
res.json({ success: true }) // Fail open
}
})Environment Variables
bash
VETTLY_API_KEY=vettly_your_api_key_hereNext Steps
- Custom Policies - Define your own rules
- Webhooks - Async notifications
- Dashboard - Monitor decisions