Skip to content

Express Integration

Add content moderation to your Express API in minutes.

Installation

bash
npm install @nextauralabs/vettly-sdk

Quick 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_here

Next Steps