Examples of how to moderate both text and image content in a single request
One of the key features of the Omni API is the ability to moderate both text and images in a single request. This is particularly useful for applications like social media posts, reviews, or comments that may contain both text and images.
curl -X POST https://api.omnimoderate.com/v1/moderate \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{
"input": [
{ "type": "text", "text": "This restaurant has amazing food!" },
{ "type": "text", "text": "The service was excellent and I highly recommend the steak." },
{ "type": "image", "base64": "data:image/jpeg;base64,/9j/4AAQSkZ..." },
{ "type": "image", "base64": "data:image/jpeg;base64,iVBORw0KGg..." }
],
"analyze_images": true
}'
{
"id": "modr-123462",
"model": "text-moderation-latest",
"results": [
{
"flagged": false,
"categories": {
"hate": false,
"harassment": false,
"self-harm": false,
"sexual": false,
"violence": false
},
"category_scores": {
"hate": 0.0,
"harassment": 0.0,
"self-harm": 0.0,
"sexual": 0.0,
"violence": 0.0
}
},
{
"flagged": false,
"categories": {
"hate": false,
"harassment": false,
"self-harm": false,
"sexual": false,
"violence": false
},
"category_scores": {
"hate": 0.0,
"harassment": 0.0,
"self-harm": 0.0,
"sexual": 0.0,
"violence": 0.0
}
},
{
"flagged": false,
"categories": {
"hate": false,
"harassment": false,
"self-harm": false,
"sexual": false,
"violence": false
},
"category_scores": {
"hate": 0.0,
"harassment": 0.0,
"self-harm": 0.0,
"sexual": 0.0,
"violence": 0.0
}
},
{
"flagged": false,
"categories": {
"hate": false,
"harassment": false,
"self-harm": false,
"sexual": false,
"violence": false
},
"category_scores": {
"hate": 0.0,
"harassment": 0.0,
"self-harm": 0.0,
"sexual": 0.0,
"violence": 0.0
}
}
],
"combined_text_moderation": {
"flagged": false,
"categories": {
"hate": false,
"harassment": false,
"self-harm": false,
"sexual": false,
"violence": false
},
"category_scores": {
"hate": 0.0,
"harassment": 0.0,
"self-harm": 0.0,
"sexual": 0.0,
"violence": 0.0
}
},
"vision_analysis": [
{
"image_index": 2,
"analysis": "This image shows a plate of beautifully presented food in what appears to be a restaurant setting. The dish looks like a well-plated steak with garnishes and side dishes. The lighting is good, the food appears appetizing, and the image is of high quality. This is perfectly appropriate for a restaurant listing or review as it showcases the food offerings. VERDICT: APPROPRIATE",
"flagged": false
},
{
"image_index": 3,
"analysis": "This image shows the interior of a restaurant with tables and chairs. The space appears clean, well-lit, and professionally designed. This is an appropriate image for a restaurant listing as it accurately represents the dining environment for potential customers. There are no inappropriate elements or overlays in the image. VERDICT: APPROPRIATE",
"flagged": false
}
],
"flagged": false,
"signature": "abcdef1234567896"
}
// Function to convert an image file to base64
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
async function moderateMixedContent(apiKey, textItems, imageFiles, analyzeImages = false) {
// Convert all image files to base64
const base64Promises = imageFiles.map(file => fileToBase64(file));
const base64Images = await Promise.all(base64Promises);
// Prepare the input array with both text and image items
const input = [
...textItems.map(text => ({ type: 'text', text })),
...base64Images.map(base64 => ({ type: 'image', base64 }))
];
const response = await fetch('https://api.omnimoderate.com/v1/moderate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey
},
body: JSON.stringify({
input,
analyze_images: analyzeImages
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error?.message || 'Moderation request failed');
}
return await response.json();
}
// Example usage with form inputs
document.getElementById('contentForm').addEventListener('submit', async (e) => {
e.preventDefault();
const apiKey = 'your_api_key_here';
const textInput = document.getElementById('textInput').value;
const textInput2 = document.getElementById('textInput2').value;
const fileInput = document.getElementById('imageInput');
const analyzeImages = document.getElementById('analyzeImages').checked;
const textItems = [textInput, textInput2].filter(text => text.trim() !== '');
const imageFiles = Array.from(fileInput.files);
try {
const result = await moderateMixedContent(apiKey, textItems, imageFiles, analyzeImages);
console.log('Moderation result:', result);
console.log('Overall flagged:', result.flagged);
// Check text results
if (textItems.length > 0) {
console.log('Combined text flagged:', result.combined_text_moderation.flagged);
textItems.forEach((_, index) => {
console.log(`Text item ${index + 1} flagged: ${result.results[index].flagged}`);
});
}
// Check image results and vision analysis
if (imageFiles.length > 0 && analyzeImages && result.vision_analysis) {
result.vision_analysis.forEach((analysis) => {
console.log(`Image ${analysis.image_index - textItems.length + 1} analysis: ${analysis.analysis}`);
console.log(`Image ${analysis.image_index - textItems.length + 1} flagged: ${analysis.flagged}`);
});
}
} catch (error) {
console.error('Error:', error.message);
}
});
import requests
import base64
from pathlib import Path
def encode_image_to_base64(image_path):
"""Convert an image file to base64 encoding with MIME type prefix"""
image_path = Path(image_path)
mime_type = f"image/{image_path.suffix[1:]}" # Remove the dot from extension
with open(image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
return f"data:{mime_type};base64,{encoded_string}"
def moderate_mixed_content(api_key, text_items, image_paths, analyze_images=False):
"""Moderate both text and images using the Omni API"""
url = "https://api.omnimoderate.com/v1/moderate"
headers = {
"Content-Type": "application/json",
"X-API-Key": api_key
}
# Convert all images to base64
base64_images = [encode_image_to_base64(path) for path in image_paths]
# Prepare the input array with both text and image items
input_data = [
*[{"type": "text", "text": text} for text in text_items],
*[{"type": "image", "base64": base64} for base64 in base64_images]
]
payload = {
"input": input_data,
"analyze_images": analyze_images
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 200:
error_data = response.json()
raise Exception(error_data.get("error", {}).get("message", "Moderation request failed"))
return response.json()
# Example usage
def example():
api_key = "your_api_key_here"
text_items = [
"This restaurant has amazing food!",
"The service was excellent and I highly recommend the steak."
]
image_paths = ["path/to/image1.jpg", "path/to/image2.png"]
try:
# Moderate mixed content with vision analysis
result = moderate_mixed_content(api_key, text_items, image_paths, analyze_images=True)
print(f"Overall moderation result: {result['flagged']}")
# Check text results
if text_items:
print(f"Combined text flagged: {result['combined_text_moderation']['flagged']}")
for i in range(len(text_items)):
print(f"Text item {i + 1} flagged: {result['results'][i]['flagged']}")
# Check image results and vision analysis
if image_paths and 'vision_analysis' in result:
for analysis in result['vision_analysis']:
image_index = analysis['image_index'] - len(text_items)
print(f"Image {image_index + 1} analysis: {analysis['analysis']}")
print(f"Image {image_index + 1} flagged: {analysis['flagged']}")
except Exception as e:
print(f"Error: {str(e)}")
if __name__ == "__main__":
example()