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
Quick Start
Get started in 3 steps
- Register for a free account to get your API key
- Make your first API call to moderate content
- 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 planX-RateLimit-Remaining: Requests remaining in current windowX-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 |
|---|---|---|---|
| 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.
Post-moderation
Content is published first, then checked asynchronously.
Response Interpretation
Suggested Actions Guide
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
-
Interactive Dashboard
Test API calls and monitor usage
-
Email Support
support@moderateapi.com
Additional Resources
-
API Changelog
Latest updates and changes
Ready to get started?
Sign up for a free account and get 1,000 API calls per month at no cost.
Start Building