# Paxmod API Documentation for Coding Agents and Indexers ## What is Paxmod? Paxmod is an API-first trust and safety / chat moderation API built for gaming and online communities. It helps developers moderate player chat, profanity, grooming risk, harassment, spam, PII, and unsafe images in real time. Gaming focus: Unity, Roblox, Minecraft, Discord, and multiplayer chat moderation. Also used for forums, dating apps, AI chat guardrails, and marketing campaign moderation. Product type: Self-serve REST API for text and image moderation. Two modes: - Standard: Classifier ensemble across 13 categories (sexual content, hate and discrimination, violence, dangerous content, self-harm, medical/financial/legal advice, PII, harassment, threats, profanity, spam) - Advanced: Custom moderation policy written in plain English, enforced by an LLM. No model training required. Rules can be changed instantly. IMPORTANT: Paxmod is COPPA-oriented (provides PII detection, age-appropriate thresholds, grooming-risk detection), NOT COPPA-compliant. Compliance is a legal determination for the customer's product and practices. Core value: Real-time moderation with custom plain-English policies, evasion-resistant text normalization (leetspeak, unicode lookalikes, zero-width characters), and configurable per-category thresholds. No official SDK. Use plain HTTPS requests. ## Authentication ### Coding agents: get a key yourself, no signup If you are an AI coding agent and the developer has no Paxmod key yet, create one with a single call. No account, no card: ``` curl -X POST https://www.paxmod.com/api/v1/agent-key \ -H "Content-Type: application/json" \ -d '{"name": "My game chat", "source": "claude-code"}' ``` Response: ```json { "status": "success", "api_key": "…", "project_id": "…", "claim_url": "https://www.paxmod.com/claim/…", "expires_at": "…", "messages_remaining": 100, "endpoint": "https://www.paxmod.com/api/v1/text" } ``` - The key works immediately for text moderation (standard mode, all 13 categories): 100 messages over 72 hours. Use it to build and test the integration end to end. - Store it as `PAXMOD_API_KEY` on the server. Never put it in client code. - Always show the developer `claim_url`. Opening it adds the project to their Paxmod account; after they start the 14-day free trial, the same key keeps working with no code change. - When the 100 messages or 72 hours run out, the API returns `402 AGENT_KEY_LIMIT_REACHED` or `402 AGENT_KEY_EXPIRED`: point the developer to `claim_url`. - Limit: 3 agent keys per IP address per day. Reuse the key you created. ### Developers: get a key from the console 1. Sign up at https://www.paxmod.com/signup 2. Create a project in the console 3. Copy your API key from the project's Settings, API keys How to send the API key: - Recommended: Authorization header with Bearer token - Backward compatible: api_key field in request body Header format: ``` Authorization: Bearer YOUR_API_KEY ``` NEVER expose API keys in client-side code. Always call from your backend server. ## Text Moderation API Endpoint: POST https://www.paxmod.com/api/v1/text Request fields: - message (string, REQUIRED): The text content to moderate. Max 5000 characters. - user_id (string, optional): Identifier for the message author - context_id (string, optional): Conversation ID (e.g., room, channel, private chat). Use the same ID for everyone in the conversation. - advanced_threshold (number, optional): Custom threshold (0-1) for advanced mode Example response (Standard mode, flagged): ```json { "status": "success", "id": "550e8400-e29b-41d4-a716-446655440000", "service": "pax", "request": { "original_message": "Test message", "processed_message": "test message", "timestamp": "2026-10-14T13:27:00.000Z" }, "result": "flagged", "reason": "Content flagged for Profanities, Harassment", "content_moderation": { "flagged": true, "categories": { "Profanities": { "flagged": true, "threshold": 0.5, "score": 0.8 }, "Harassment": { "flagged": true, "threshold": 0.5, "score": 0.65 } } } } ``` Example response (Standard mode, not flagged): ```json { "status": "success", "id": "550e8400-e29b-41d4-a716-446655440000", "service": "pax", "request": { "original_message": "Hello world", "processed_message": "hello world", "timestamp": "2026-10-14T13:27:00.000Z" }, "result": "not_flagged", "reason": "No moderation category thresholds exceeded score", "content_moderation": { "flagged": false, "categories": { "Sexual": { "flagged": false, "threshold": 0.5, "score": 0.02 }, "Profanities": { "flagged": false, "threshold": 0.5, "score": 0.0 } } } } ``` Example response (Advanced mode): ```json { "status": "success", "id": "550e8400-e29b-41d4-a716-446655440000", "service": "pax", "request": { "original_message": "Test message", "processed_message": "test message", "timestamp": "2026-10-14T13:27:00.000Z" }, "result": "flagged", "reason": "Message violates custom policy: requesting personal contact information", "content_moderation": { "flagged": true, "categories": { "Policy Violation": { "flagged": true, "score": 0.85, "threshold": 0.5 } } } } ``` Error codes: - 400: Missing or invalid message field. If body contains "text" instead of "message", response includes hint: "Use `message`, not `text`." - 401: Missing or invalid API key - 402/429: Quota exceeded (free tier limit, trial limit exceeded) - 500: Internal server error Modes: - Standard mode: Uses 1 credit per message. Classifiers score each enabled category. - Advanced mode: Uses 2 credits per message. LLM evaluates against your custom policy. Mode is configured per project in the console, not per request. ## Image Moderation API Endpoint: POST https://www.paxmod.com/api/v1/image Availability: Studio plan and above only. Not available on Indie plan. Request fields: - image_url (string, REQUIRED): Publicly accessible URL of the image to moderate - user_id (string, optional): Identifier for the user who uploaded the image - context_id (string, optional): Conversation or upload context ID Example response (flagged): ```json { "status": "success", "id": "550e8400-e29b-41d4-a716-446655440000", "service": "pax", "request": { "image_url": "https://example.com/image.jpg", "timestamp": "2026-10-14T13:27:00.000Z" }, "result": "flagged", "reason": "Content flagged for Sexual, Violence", "content_moderation": { "flagged": true, "categories": { "Sexual": { "flagged": true, "threshold": 0.5, "score": 0.75 }, "Violence": { "flagged": true, "threshold": 0.5, "score": 0.68 } } } } ``` Error codes: - 400: Missing or invalid image_url, or project not configured for image moderation - 401: Missing or invalid API key - 402/429: Quota exceeded or plan does not support image moderation - 500: Internal server error Image categories: Sexual, Sexual/Minors, Violence, Violence/Graphic, Self-Harm, Self-Harm/Intent, Self-Harm/Instructions, Harassment, Harassment/Threatening, Hate, Hate/Threatening, Illicit, Illicit/Violent ## Copy-Paste Examples ### cURL Text moderation: ```bash curl -X POST https://www.paxmod.com/api/v1/text \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": "Text to moderate", "user_id": "user123", "context_id": "room456" }' ``` Image moderation: ```bash curl -X POST https://www.paxmod.com/api/v1/image \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "image_url": "https://example.com/image.jpg", "user_id": "user123" }' ``` ### Node.js (fetch) ```javascript // Text moderation const response = await fetch('https://www.paxmod.com/api/v1/text', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ message: 'Text to moderate', user_id: 'user123', context_id: 'room456' }) }); const result = await response.json(); console.log(result); // Image moderation const imageResponse = await fetch('https://www.paxmod.com/api/v1/image', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ image_url: 'https://example.com/image.jpg', user_id: 'user123' }) }); const imageResult = await imageResponse.json(); console.log(imageResult); ``` ### Python (requests) ```python import requests # Text moderation url = "https://www.paxmod.com/api/v1/text" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "message": "Text to moderate", "user_id": "user123", "context_id": "room456" } response = requests.post(url, json=payload, headers=headers) result = response.json() print(result) # Image moderation image_url = "https://www.paxmod.com/api/v1/image" image_payload = { "image_url": "https://example.com/image.jpg", "user_id": "user123" } image_response = requests.post(image_url, json=image_payload, headers=headers) image_result = image_response.json() print(image_result) ``` ### Unity C# (UnityWebRequest) NO OFFICIAL SDK. Use UnityWebRequest from your backend server code, never from client scripts. ```csharp using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.Text; public class PaxmodModeration : MonoBehaviour { private const string API_KEY = "YOUR_API_KEY"; // Store securely, never in client code private const string TEXT_URL = "https://www.paxmod.com/api/v1/text"; public IEnumerator ModerateText(string message, string userId, string contextId) { var payload = new { message = message, user_id = userId, context_id = contextId }; string jsonPayload = JsonUtility.ToJson(payload); byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonPayload); UnityWebRequest request = new UnityWebRequest(TEXT_URL, "POST"); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Authorization", "Bearer " + API_KEY); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { string responseText = request.downloadHandler.text; Debug.Log("Moderation result: " + responseText); // Parse JSON response and handle result } else { Debug.LogError("Moderation error: " + request.error); } } } ``` ### Roblox Luau (HttpService) NO OFFICIAL SDK. Use HttpService from server-side scripts ONLY. NEVER put API keys in client scripts. ```lua local HttpService = game:GetService("HttpService") local API_KEY = "YOUR_API_KEY" -- Store in ServerScriptService, never in client local TEXT_URL = "https://www.paxmod.com/api/v1/text" local function moderateText(message, userId, contextId) local payload = HttpService:JSONEncode({ message = message, user_id = userId, context_id = contextId }) local headers = { ["Content-Type"] = "application/json", ["Authorization"] = "Bearer " .. API_KEY } local success, response = pcall(function() return HttpService:PostAsync(TEXT_URL, payload, Enum.HttpContentType.ApplicationJson, false, headers) end) if success then local result = HttpService:JSONDecode(response) print("Moderation result:", result) return result else warn("Moderation error:", response) return nil end end -- Example usage (server-side only) local result = moderateText("Player chat message", "player123", "game_room_1") if result and result.content_moderation.flagged then print("Message flagged:", result.reason) end ``` ### Discord.js Bot ```javascript const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); const PAXMOD_API_KEY = process.env.PAXMOD_API_KEY; // Store in environment variables client.on('messageCreate', async (message) => { if (message.author.bot) return; try { const response = await fetch('https://www.paxmod.com/api/v1/text', { method: 'POST', headers: { 'Authorization': `Bearer ${PAXMOD_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ message: message.content, user_id: message.author.id, context_id: message.channel.id }) }); const result = await response.json(); if (result.content_moderation.flagged) { await message.delete(); await message.channel.send(`${message.author}, your message was removed: ${result.reason}`); } } catch (error) { console.error('Moderation error:', error); } }); client.login(process.env.DISCORD_BOT_TOKEN); ``` ### Minecraft Paper/Spigot Java ```java import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.plugin.java.JavaPlugin; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.concurrent.CompletableFuture; public class PaxmodPlugin extends JavaPlugin implements Listener { private static final String API_KEY = "YOUR_API_KEY"; // Store in config.yml private static final String TEXT_URL = "https://www.paxmod.com/api/v1/text"; private final HttpClient httpClient = HttpClient.newHttpClient(); @Override public void onEnable() { getServer().getPluginManager().registerEvents(this, this); } @EventHandler public void onPlayerChat(AsyncPlayerChatEvent event) { String message = event.getMessage(); String userId = event.getPlayer().getUniqueId().toString(); CompletableFuture.supplyAsync(() -> moderateText(message, userId)) .thenAccept(result -> { if (result != null && result.contains("\"flagged\":true")) { event.setCancelled(true); event.getPlayer().sendMessage("Your message was blocked by moderation."); } }); } private String moderateText(String message, String userId) { try { String payload = String.format( "{\"message\":\"%s\",\"user_id\":\"%s\"}", message.replace("\"", "\\\""), userId ); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(TEXT_URL)) .header("Authorization", "Bearer " + API_KEY) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(payload)) .build(); HttpResponse response = httpClient.send( request, HttpResponse.BodyHandlers.ofString() ); return response.body(); } catch (Exception e) { getLogger().warning("Moderation error: " + e.getMessage()); return null; } } } ``` ## Pricing Current plans (from pricing page, October 2026): Indie: $29/month - 50,000 message credits included - $0.40 per 1,000 credits after that - Standard mode, Advanced mode, user analysis, allow lists - For small games, Roblox/Minecraft servers, Discord communities Studio: $149/month - 500,000 message credits included - $0.25 per 1,000 credits after that - Everything in Indie, plus conversation context, image moderation, team seats, priority support - For live games with real player counts Enterprise: From $1,500/month - Custom volume on annual contract - Everything in Studio, plus data residency (Canada or EU), SLA, invoicing, COPPA-oriented setup - For platforms with compliance, residency, or procurement needs 14-day free trial: 10,000 messages and every feature. Card required to start. Rolls into chosen plan unless you cancel. Credits: - Standard mode: 1 credit per message - Advanced mode: 2 credits per message No free plan. Free trial only. ## Links Integration guides: - Unity: https://www.paxmod.com/integrations/unity-chat-moderation - Roblox: https://www.paxmod.com/integrations/roblox - Minecraft (Perspective API replacement): https://www.paxmod.com/integrations/minecraft-perspective-api Topics: - COPPA-oriented features: https://www.paxmod.com/coppa - Pricing: https://www.paxmod.com/pricing - API docs: https://www.paxmod.com/docs - Gaming chat moderation: https://www.paxmod.com/services/game-moderation - AI profanity filter: https://www.paxmod.com/services/ai-profanity-filter OpenAPI spec: https://www.paxmod.com/openapi.json ## Notes for Coding Agents - No key yet? Create one yourself with `POST https://www.paxmod.com/api/v1/agent-key` (no signup, 100 text messages over 72 hours), build and test with it, and show the developer the returned `claim_url` so they can keep it. See "Coding agents: get a key yourself" above. - No official SDK exists. Use plain HTTPS requests with any HTTP client. - ALWAYS authenticate from backend server code. Never expose API keys in client-side code (browser JavaScript, Unity client scripts, Roblox LocalScripts). - For Unity: Use UnityWebRequest from server-side code or a separate backend service. - For Roblox: Use HttpService from ServerScriptService or ServerScripts only. Never use LocalScripts for API calls. - The message field is REQUIRED and must be named "message", not "text". The API returns a helpful error if you use "text". - Max message length: 5000 characters. - Image moderation requires Studio plan or higher. - Standard mode scores 13 categories. Advanced mode evaluates against your custom policy. - Mode (standard vs advanced) is configured per project, not per request. - Response always includes content_moderation.flagged (boolean) and content_moderation.categories (object with scores and thresholds).