ModerateAPI Documentation

ModerateAPI provides intelligent content moderation through a simple REST API. Protect your platform from toxic content, spam, and harmful material with AI-powered detection.

API Base URL

https://moderateapi.com/api/v1

99.9%
Uptime SLA
<100ms
Avg Response Time
24/7
Support Available

Quick Start

Get started in 3 steps

  1. Register for a free account to get your API key
  2. Make your first API call to moderate content
  3. Integrate into your application

1. Get Your API Key

First, register for an account to receive your API key:

curl -X POST https://moderateapi.com/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "your@email.com",
    "password": "your_secure_password"
  }'

Response:

{
  "success": true,
  "message": "User created successfully",
  "user_id": 123,
  "api_key": {
    "key": "mk_abc123...",
    "name": "Default Key",
    "prefix": "mk_abc12"
  },
  "plan": "free",
  "monthly_limit": 1000
}

2. Make Your First Request

Test the moderation API with some content:

curl -X POST https://moderateapi.com/api/v1/moderate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "text": "This is a test message",
    "context": "comment"
  }'

Response:

{
  "safe": true,
  "confidence": 0.95,
  "issues": [],
  "suggested_action": "approve",
  "from_cache": false,
  "request_id": "unique_id",
  "response_time_ms": 85,
  "text_length": 21
}

Authentication

ModerateAPI uses API keys for authentication. Include your API key in the request header:

API Key Format

API keys start with mk_ followed by 64 characters. Example: mk_abc123def456...

Header Authentication

Include your API key in the X-API-Key header:

POST /api/v1/moderate HTTP/1.1
Host: moderateapi.com
Content-Type: application/json
X-API-Key: mk_your_api_key_here

{
  "text": "Content to moderate"
}

Bearer Token Authentication

Alternatively, use the Authorization header with Bearer token format:

POST /api/v1/moderate HTTP/1.1
Host: moderateapi.com
Content-Type: application/json
Authorization: Bearer mk_your_api_key_here

{
  "text": "Content to moderate"
}

Security Best Practices

  • Never expose API keys in client-side code
  • Store API keys securely in environment variables
  • Use separate API keys for different environments
  • Rotate API keys regularly

Rate Limits

Rate limits are enforced per API key and vary by subscription plan. When you exceed the rate limit, you'll receive a 429 Too Many Requests response.

Plan Monthly Limit Rate Limit Price
Free 1,000 requests 10/minute $0
Starter 10,000 requests 50/minute $19
Growth 100,000 requests 200/minute $99
Scale 500,000 requests 500/minute $299

Rate Limit Headers

All API responses include rate limit information in the headers:

HTTP/1.1 200 OK
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1640995200
  • X-RateLimit-Limit: Maximum requests per minute for your plan
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: Unix timestamp when the rate limit resets

Error Handling

ModerateAPI uses conventional HTTP response codes to indicate the success or failure of API requests.

Code Status Description
200 OK Everything worked as expected
400 Bad Request Invalid request (missing parameters, malformed JSON, etc.)
401 Unauthorized Invalid or missing API key
403 Forbidden Subscription cancelled or suspended
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Something went wrong on our end

Error Response Format

All error responses include a JSON object with an error message:

{
  "error": "API key required",
  "request_id": "req_abc123",
  "timestamp": "2024-01-15T10:30:00Z"
}

Handling Errors in Code

Always check the HTTP status code and handle errors gracefully:

try {
  const response = await fetch('https://moderateapi.com/api/v1/moderate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': 'your-api-key'
    },
    body: JSON.stringify({ text: 'Content to moderate' })
  });

  if (!response.ok) {
    if (response.status === 429) {
      console.log('Rate limit exceeded, please wait');
      return;
    }
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }

  const result = await response.json();
  console.log('Moderation result:', result);
} catch (error) {
  console.error('Moderation failed:', error.message);
}

User Registration

Create a new user account and generate an API key. New accounts start with the free tier.

Endpoint

POST /api/v1/register

Request Body

Parameter Type Required Description
email string Valid email address
password string Minimum 8 characters

Example Request

curl -X POST https://moderateapi.com/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "developer@example.com",
    "password": "secure_password123"
  }'

Example Response

{
  "success": true,
  "message": "User created successfully",
  "user_id": 123,
  "api_key": {
    "key": "mk_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2v3w4x5y6z7a8b9c0d1e2f3g4h",
    "name": "Default Key",
    "prefix": "mk_1a2b3c"
  },
  "plan": "free",
  "monthly_limit": 1000,
  "usage": {
    "current_month": 0,
    "remaining": 1000
  }
}

Content Moderation

The core endpoint for moderating text content. Analyzes text for toxicity, spam, inappropriate content, and other policy violations.

Endpoint

POST /api/v1/moderate

Request Headers

Content-Type: application/json
X-API-Key: mk_your_api_key_here

Request Body

Parameter Type Required Description
text string Content to moderate (max 50,000 characters)
context string - Context hint (comment, review, message, etc.)

Example Request

curl -X POST https://moderateapi.com/api/v1/moderate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: mk_your_api_key_here" \
  -d '{
    "text": "Hey everyone! Check out this amazing product, click here to win $1000 now!",
    "context": "comment"
  }'

Example Response

{
  "safe": false,
  "confidence": 0.87,
  "issues": [
    {
      "type": "spam",
      "severity": "medium",
      "confidence": 0.85
    },
    {
      "type": "urgency_scam",
      "severity": "high",
      "confidence": 0.78
    }
  ],
  "suggested_action": "block",
  "from_cache": false,
  "request_id": "req_abc123def456",
  "response_time_ms": 152,
  "text_length": 79
}

Response Fields

Field Type Description
safe boolean Whether the content is considered safe
confidence float Confidence score (0.0 - 1.0)
issues array List of detected issues
suggested_action string approve, warn, or block
from_cache boolean Whether result was cached

Issue Types

Content Issues

  • • toxicity
  • • hate_speech
  • • harassment
  • • profanity

Spam & Scams

  • • spam
  • • urgency_scam
  • • contact_info
  • • blocked_word

Usage Statistics

Get detailed usage statistics for your account, including current month usage, limits, and API key information.

Endpoint

GET /api/v1/usage

Request Headers

X-API-Key: mk_your_api_key_here

Example Request

curl -X GET https://moderateapi.com/api/v1/usage \
  -H "X-API-Key: mk_your_api_key_here"

Example Response

{
  "user_id": 123,
  "plan": {
    "name": "growth",
    "display_name": "Growth Plan",
    "monthly_limit": 100000,
    "rate_limit": 200
  },
  "current_month": {
    "calls_used": 15420,
    "calls_limit": 100000,
    "remaining_calls": 84580,
    "usage_percentage": 15.42,
    "period_start": "2024-01-01T00:00:00Z",
    "period_end": "2024-01-31T23:59:59Z"
  },
  "api_keys": [
    {
      "name": "Production Key",
      "prefix": "mk_1a2b3c",
      "created": "2024-01-01T10:30:00Z",
      "last_used": "2024-01-15T14:22:33Z",
      "status": "active",
      "calls_this_month": 15420
    }
  ],
  "billing": {
    "subscription_status": "active",
    "next_billing_date": "2024-02-01T00:00:00Z",
    "amount": 99.00,
    "currency": "USD"
  }
}

Response Fields

Field Type Description
plan object Current subscription plan details
current_month object Current billing period usage
api_keys array List of API keys for this account
billing object Billing and subscription information

Code Examples

JavaScript

Node.js with fetch

const API_KEY = 'mk_your_api_key_here';
const BASE_URL = 'https://moderateapi.com/api/v1';

async function moderateContent(text, context = null) {
  try {
    const response = await fetch(`${BASE_URL}/moderate`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': API_KEY
      },
      body: JSON.stringify({
        text: text,
        ...(context && { context })
      })
    });

    if (!response.ok) {
      if (response.status === 429) {
        throw new Error('Rate limit exceeded. Please wait before making more requests.');
      }
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    const result = await response.json();
    return result;
  } catch (error) {
    console.error('Moderation failed:', error.message);
    throw error;
  }
}

// Usage example
async function main() {
  try {
    const result = await moderateContent(
      "This is some content to moderate",
      "comment"
    );

    console.log('Safe:', result.safe);
    console.log('Confidence:', result.confidence);
    console.log('Action:', result.suggested_action);

    if (result.issues.length > 0) {
      console.log('Issues found:');
      result.issues.forEach(issue => {
        console.log(`- ${issue.type} (${issue.severity}): ${issue.confidence}`);
      });
    }
  } catch (error) {
    console.error('Error:', error.message);
  }
}

main();

Browser JavaScript with Error Handling

class ModerateAPIClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://moderateapi.com/api/v1';
    this.rateLimitRetries = 3;
  }

  async moderate(text, context = null, retryCount = 0) {
    try {
      const response = await fetch(`${this.baseUrl}/moderate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-API-Key': this.apiKey
        },
        body: JSON.stringify({
          text: text,
          ...(context && { context })
        })
      });

      if (response.status === 429 && retryCount < this.rateLimitRetries) {
        // Exponential backoff for rate limiting
        const delay = Math.pow(2, retryCount) * 1000;
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        return this.moderate(text, context, retryCount + 1);
      }

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(errorData.error || `HTTP ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      if (error.name === 'TypeError' && error.message.includes('fetch')) {
        throw new Error('Network error. Please check your connection.');
      }
      throw error;
    }
  }

  async getUsage() {
    const response = await fetch(`${this.baseUrl}/usage`, {
      headers: { 'X-API-Key': this.apiKey }
    });

    if (!response.ok) {
      throw new Error(`Failed to get usage: ${response.status}`);
    }

    return await response.json();
  }
}

// Usage
const client = new ModerateAPIClient('mk_your_api_key_here');

client.moderate('Content to check')
  .then(result => {
    if (result.safe) {
      console.log('✅ Content is safe');
    } else {
      console.log('⚠️ Content flagged:', result.issues);
    }
  })
  .catch(error => console.error('Error:', error.message));

Python

Using requests library

import requests
import time
from typing import Optional, Dict, Any

class ModerateAPIClient:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = 'https://moderateapi.com/api/v1'
        self.session = requests.Session()
        self.session.headers.update({
            'X-API-Key': api_key,
            'Content-Type': 'application/json'
        })

    def moderate(self, text: str, context: Optional[str] = None,
                 max_retries: int = 3) -> Dict[str, Any]:
        """
        Moderate text content using the ModerateAPI service.

        Args:
            text: Content to moderate
            context: Optional context hint
            max_retries: Maximum retry attempts for rate limiting

        Returns:
            Dictionary containing moderation results

        Raises:
            requests.RequestException: For API errors
        """
        payload = {'text': text}
        if context:
            payload['context'] = context

        for attempt in range(max_retries + 1):
            try:
                response = self.session.post(
                    f'{self.base_url}/moderate',
                    json=payload,
                    timeout=30
                )

                if response.status_code == 429:  # Rate limited
                    if attempt < max_retries:
                        delay = 2 ** attempt  # Exponential backoff
                        print(f"Rate limited. Waiting {delay}s before retry...")
                        time.sleep(delay)
                        continue
                    else:
                        raise requests.RequestException("Rate limit exceeded")

                response.raise_for_status()
                return response.json()

            except requests.RequestException as e:
                if attempt == max_retries:
                    raise
                print(f"Request failed (attempt {attempt + 1}): {e}")
                time.sleep(1)

    def get_usage(self) -> Dict[str, Any]:
        """Get account usage statistics."""
        response = self.session.get(f'{self.base_url}/usage')
        response.raise_for_status()
        return response.json()

    def register_user(self, email: str, password: str) -> Dict[str, Any]:
        """Register a new user account."""
        response = requests.post(
            f'{self.base_url}/register',
            json={'email': email, 'password': password}
        )
        response.raise_for_status()
        return response.json()

# Usage example
def main():
    client = ModerateAPIClient('mk_your_api_key_here')

    try:
        # Moderate some content
        result = client.moderate(
            "This is some text to check for safety",
            context="comment"
        )

        print(f"Safe: {result['safe']}")
        print(f"Confidence: {result['confidence']:.2f}")
        print(f"Suggested action: {result['suggested_action']}")

        if result['issues']:
            print("\nIssues detected:")
            for issue in result['issues']:
                print(f"  - {issue['type']} ({issue['severity']}): "
                      f"{issue['confidence']:.2f}")

        # Check usage
        usage = client.get_usage()
        print(f"\nAPI Usage: {usage['current_month']['calls_used']} / "
              f"{usage['current_month']['calls_limit']}")

    except requests.RequestException as e:
        print(f"API Error: {e}")

if __name__ == "__main__":
    main()

Async Python with aiohttp

import aiohttp
import asyncio
from typing import Optional, Dict, Any, List

class AsyncModerateAPIClient:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = 'https://moderateapi.com/api/v1'
        self.headers = {
            'X-API-Key': api_key,
            'Content-Type': 'application/json'
        }

    async def moderate(self, text: str, context: Optional[str] = None) -> Dict[str, Any]:
        """Moderate text content asynchronously."""
        payload = {'text': text}
        if context:
            payload['context'] = context

        async with aiohttp.ClientSession() as session:
            async with session.post(
                f'{self.base_url}/moderate',
                json=payload,
                headers=self.headers
            ) as response:
                if response.status == 429:
                    raise aiohttp.ClientResponseError(
                        None, None, status=429,
                        message="Rate limit exceeded"
                    )
                response.raise_for_status()
                return await response.json()

    async def moderate_batch(self, texts: List[str],
                           context: Optional[str] = None) -> List[Dict[str, Any]]:
        """Moderate multiple texts concurrently."""
        tasks = [self.moderate(text, context) for text in texts]
        return await asyncio.gather(*tasks, return_exceptions=True)

# Usage example
async def main():
    client = AsyncModerateAPIClient('mk_your_api_key_here')

    # Single moderation
    result = await client.moderate("Text to moderate")
    print(f"Result: {result['safe']}")

    # Batch moderation
    texts = [
        "First comment to check",
        "Second comment to check",
        "Third comment to check"
    ]

    results = await client.moderate_batch(texts, context="comment")

    for i, result in enumerate(results):
        if isinstance(result, Exception):
            print(f"Text {i+1} failed: {result}")
        else:
            print(f"Text {i+1}: {'Safe' if result['safe'] else 'Flagged'}")

# Run the async example
# asyncio.run(main())

PHP

Using cURL

<?php

class ModerateAPIClient {
    private $apiKey;
    private $baseUrl;

    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
        $this->baseUrl = 'https://moderateapi.com/api/v1';
    }

    public function moderate($text, $context = null) {
        $data = ['text' => $text];
        if ($context) {
            $data['context'] = $context;
        }

        $response = $this->makeRequest('POST', '/moderate', $data);
        return $response;
    }

    public function getUsage() {
        return $this->makeRequest('GET', '/usage');
    }

    public function registerUser($email, $password) {
        $data = [
            'email' => $email,
            'password' => $password
        ];
        return $this->makeRequest('POST', '/register', $data, false);
    }

    private function makeRequest($method, $endpoint, $data = null, $useAuth = true) {
        $url = $this->baseUrl . $endpoint;

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $this->getHeaders($useAuth),
            CURLOPT_SSL_VERIFYPEER => true,
        ]);

        if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }

        $decodedResponse = json_decode($response, true);

        if ($httpCode >= 400) {
            $errorMessage = isset($decodedResponse['error'])
                ? $decodedResponse['error']
                : "HTTP $httpCode";
            throw new Exception($errorMessage);
        }

        return $decodedResponse;
    }

    private function getHeaders($useAuth = true) {
        $headers = ['Content-Type: application/json'];

        if ($useAuth) {
            $headers[] = 'X-API-Key: ' . $this->apiKey;
        }

        return $headers;
    }
}

// Usage example
try {
    $client = new ModerateAPIClient('mk_your_api_key_here');

    // Moderate content
    $result = $client->moderate(
        "This is some content to check",
        "comment"
    );

    echo "Safe: " . ($result['safe'] ? 'Yes' : 'No') . "\n";
    echo "Confidence: " . round($result['confidence'], 2) . "\n";
    echo "Action: " . $result['suggested_action'] . "\n";

    if (!empty($result['issues'])) {
        echo "\nIssues detected:\n";
        foreach ($result['issues'] as $issue) {
            echo "- {$issue['type']} ({$issue['severity']}): " .
                 round($issue['confidence'], 2) . "\n";
        }
    }

    // Check usage
    $usage = $client->getUsage();
    echo "\nAPI Usage: {$usage['current_month']['calls_used']} / " .
         "{$usage['current_month']['calls_limit']}\n";

} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

?>

cURL

Basic moderation request

# Basic content moderation
curl -X POST https://moderateapi.com/api/v1/moderate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: mk_your_api_key_here" \
  -d '{
    "text": "This is content to moderate",
    "context": "comment"
  }'

User registration

# Register new user
curl -X POST https://moderateapi.com/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "secure_password123"
  }'

Get usage statistics

# Get account usage
curl -X GET https://moderateapi.com/api/v1/usage \
  -H "X-API-Key: mk_your_api_key_here"

With error handling

#!/bin/bash

API_KEY="mk_your_api_key_here"
BASE_URL="https://moderateapi.com/api/v1"

# Function to moderate content with error handling
moderate_content() {
    local text="$1"
    local context="${2:-}"

    local payload="{\"text\": \"$text\""
    if [ -n "$context" ]; then
        payload="$payload, \"context\": \"$context\""
    fi
    payload="$payload}"

    response=$(curl -s -w "%{http_code}" -X POST "$BASE_URL/moderate" \
        -H "Content-Type: application/json" \
        -H "X-API-Key: $API_KEY" \
        -d "$payload")

    http_code="${response: -3}"
    body="${response%???}"

    case $http_code in
        200)
            echo "Success: $body"
            ;;
        400)
            echo "Bad Request: $body"
            exit 1
            ;;
        401)
            echo "Unauthorized: Check your API key"
            exit 1
            ;;
        429)
            echo "Rate limited: Please wait before trying again"
            exit 1
            ;;
        *)
            echo "Error $http_code: $body"
            exit 1
            ;;
    esac
}

# Usage
moderate_content "Content to check" "comment"

Best Practices

Security Best Practices

  • Store API keys securely in environment variables, never in code
  • Use different API keys for development, staging, and production
  • Rotate API keys regularly and when team members leave
  • Never expose API keys in client-side JavaScript or public repositories

Performance Optimization

  • Cache results locally when appropriate to reduce API calls
  • Use batch processing for multiple items when possible
  • Implement request timeouts to handle slow responses
  • Monitor your usage to optimize plan selection

Error Handling Strategies

Implement Robust Error Handling

Rate Limiting (429 errors)

Use exponential backoff with jitter. Wait 1s, 2s, 4s, etc. before retrying.

Network Failures

Implement timeouts and retry logic. Consider circuit breaker patterns for high-volume applications.

API Errors (4xx/5xx)

Log errors with context, but don't retry 4xx errors except for 429.

Content Moderation Strategies

Pre-moderation

Check content before it's published or visible to users.

Use cases: User-generated content, comments, reviews

Post-moderation

Content is published first, then checked asynchronously.

Use cases: High-volume platforms, real-time chat

Response Interpretation

Suggested Actions Guide

approve
Content is safe to publish without restrictions
warn
Content may be questionable, consider human review
block
Content should be blocked or require manual approval

Integration Patterns

Middleware Pattern

Integrate moderation as middleware in your application pipeline.

// Express.js middleware example
const moderationMiddleware = async (req, res, next) => {
  if (req.body.content) {
    try {
      const result = await moderateAPI.moderate(req.body.content);

      if (result.suggested_action === 'block') {
        return res.status(400).json({
          error: 'Content violates community guidelines'
        });
      }

      if (result.suggested_action === 'warn') {
        req.moderationWarning = true;
      }

      req.moderationResult = result;
    } catch (error) {
      console.error('Moderation failed:', error);
      // Continue without blocking if moderation service is down
    }
  }
  next();
};

Queue-based Processing

Use message queues for high-volume or non-blocking moderation.

# Python with Celery example
from celery import Celery

app = Celery('moderation')

@app.task
def moderate_content_async(content_id, text):
    try:
        result = moderate_api.moderate(text)

        # Update database with moderation result
        update_content_status(content_id, result)

        if not result['safe']:
            # Notify moderators or take action
            handle_flagged_content(content_id, result)

    except Exception as e:
        # Handle error and possibly retry
        logger.error(f"Moderation failed for {content_id}: {e}")
        raise

Webhooks

Webhooks allow you to receive real-time notifications when moderation events occur. This enables you to build reactive systems that respond immediately to content moderation results.

Coming Soon

Webhook functionality is currently in development. This feature will be available in a future release.

Planned Webhook Events

moderation.completed

Triggered when content moderation is completed

{
  "event": "moderation.completed",
  "data": {
    "request_id": "req_abc123",
    "safe": false,
    "confidence": 0.96,
    "suggested_action": "block"
  }
}

usage.limit_reached

Triggered when usage limits are approached or exceeded

{
  "event": "usage.limit_reached",
  "data": {
    "user_id": 123,
    "usage_percentage": 90,
    "calls_remaining": 100
  }
}

Webhook Configuration

When available, webhooks will be configurable through the dashboard. You'll be able to:

  • Set webhook URLs for different event types
  • Configure retry policies for failed deliveries
  • Test webhook endpoints with sample payloads
  • View delivery logs and debugging information
  • Secure webhooks with signature verification

Stay Updated

Want to be notified when webhooks are available? Contact us to join our early access list.

API Changelog

Stay up-to-date with the latest changes, improvements, and new features in ModerateAPI.

Current Status

ModerateAPI is actively in development. This changelog will be updated as new versions are released.

Upcoming Features

  • Webhooks: Real-time notifications for moderation events
  • Square Integration: Subscription management and billing
  • Custom Rules: User-defined moderation criteria
  • Bulk API: Process multiple items in a single request
  • Analytics Dashboard: Advanced usage insights and trends

Support & Resources

Get Help

Additional Resources

Ready to get started?

Sign up for a free account and get 1,000 API calls per month at no cost.

Start Building