Batch Moderation API
Submit bounded text batches when MaaS and its job queue are enabled. Read stored progress and results using the returned job ID.
Endpoints
/api/v1/moderation/batch/api/v1/moderation/batch/:id?includeResults=trueBatch Size Limits
Each request accepts 1–100 items and must also fit your account's batchSizeLimit. The lower limit applies. Oversized batches or duplicate external IDs return 400. An unavailable queue returns 503.
Keep the same body idempotencyKey when retrying a submission. Replays return the existing job; a previously failed job returns 409. Completion depends on the queue and required moderation providers.
Create Batch Job
/api/v1/moderation/batchRequest Body
| Parameter | Type |
|---|---|
itemsrequiredArray of items to moderate. | array |
items[].externalIdrequiredYour identifier, unique within this batch (1–255 characters). | string |
items[].contentrequiredContent to moderate (max 100,000 chars). | string |
items[].contentTypeUse "text". Image and mixed moderation are currently unavailable. | stringDefault: "text" |
webhookUrlSelect an active registered customer webhook subscribed to moderation.batch.complete. Omit to notify all subscribed endpoints. Unknown or inactive URLs return 400 before job creation. | string |
priorityOne of: "low", "normal", "high". | stringDefault: "normal" |
rulesConfigSame as single moderation endpoint. | object |
idempotencyKeyStable body key (1–255 characters). Reuse it for the same submission; SDKs generate one when omitted. | string |
Example Request
{
"items": [
{ "externalId": "post_123", "content": "Hello world!" },
{ "externalId": "post_456", "content": "Check out this deal!" },
{ "externalId": "post_789", "content": "Great discussion here" }
],
"idempotencyKey": "import-2026-10-09-part-1",
"priority": "normal",
"rulesConfig": {
"useGlobalSafety": true
}
}Accepted Response
HTTP 202 returns success=true and data containing jobId, status="queued", and itemsTotal. These describe acceptance, not completed moderation.
const job = await client.moderateBatch(request);
console.log(job.jobId, job.status, job.itemsTotal);Get Batch Status
/api/v1/moderation/batch/:id?includeResults=truePath and Query Parameters
| Parameter | Type |
|---|---|
id (path)requiredThe jobId returned from create. Jobs are scoped to your customer. | string |
includeResultsInclude individual item results in response. | booleanDefault: false |
Response
This endpoint returns the job object directly, with id, status, created_at, completed_at, items_total, items_processed, items_succeeded, items_failed, and results_url. With includeResults=true, results contains externalId, status, decision, confidence, rulesTriggered, explanation, and error for each item. Pending or failed items can have null decision and confidence. HTTP confidence is normalized to 0–1. Inspect item status and error before using a decision.
const status = await client.getBatchStatus(job.jobId, true);
console.log(status.status, status.items_processed, status.items_total);
console.log(status.results);Batch Status Values
| Status | Description |
|---|---|
| queued | Batch is queued and waiting to be processed. |
| processing | Batch is actively being processed. |
| completed | All items were attempted. Check items_failed and individual results. |
| failed | Batch processing failed entirely. |
Webhook Payload
The worker dispatches moderation.batch.complete to registered customer webhooks. Its envelope contains eventId, eventType, timestamp, customerId, and data. The data contains batchId, status, itemsTotal, itemsSucceeded, itemsFailed, results, and resultsUrl. Webhook item confidence uses the same normalized 0–1 scale as the status endpoint. Delivery is at least once: deduplicate using eventId, which remains the batch UUID across retries. The payload timestamp also remains stable. A failed callback can retry after moderation completes without charging for the items again.
Use the tenant-scoped GET endpoint with includeResults=true to fetch full results.
Complete Example
import { CommunitAIModerator } from '@communitai/maas';
import { env } from '@/env';
const client = new CommunitAIModerator({
apiKey: env.COMMUNITAI_API_KEY, // Import your application's validated server configuration.
});
// Create batch job
const batch = await client.moderateBatch({
items: [
{ externalId: 'post_123', content: 'Hello world!' },
{ externalId: 'post_456', content: 'Great discussion here' },
],
});
console.log(`Batch ${batch.jobId} submitted with ${batch.itemsTotal} items`);
// Poll for results (alternative to webhook)
const deadline = Date.now() + 120_000; // Application polling budget.
let status = await client.getBatchStatus(batch.jobId, true);
while (status.status === 'queued' || status.status === 'processing') {
if (Date.now() >= deadline) throw new Error('Batch is still processing; resume later');
await new Promise(resolve => setTimeout(resolve, 1000));
status = await client.getBatchStatus(batch.jobId, true);
console.log(`Progress: ${status.items_processed}/${status.items_total}`);
}
for (const result of status.results ?? []) {
console.log(result.externalId, result.status, result.decision, result.error);
}