> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnifence.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit a text moderation batch

> Submit 1 to 99 texts in one request. Each item is checked on its own, exactly as `/moderate/text` checks one text, and gets its own decision under the `key` you gave it. One batch request counts as one request against your rate limit; each item is billed as one text moderation. Each item is also an ordinary text job, so `GET /job/{job_id}` reads it. When every item has a final decision or has failed, one webhook carries all the decisions. The batch is accepted whole or refused whole: an empty batch (`BATCH_EMPTY`), more than 99 items (`BATCH_TOO_LARGE`), a repeated key (`DUPLICATE_ITEM_KEY`), a text over 20,000 characters (`TEXT_TOO_LONG`) or any other invalid item (`INVALID_REQUEST`) refuses the request with 400, and nothing is charged.

<Note>
  Requires the `moderate:text` scope. Requests without this scope receive a `403 FORBIDDEN`
  response. See [authentication](/authentication#scopes).
</Note>

<Note>
  A batch holds 1 to 99 items. Each `text` is limited to 20,000 characters, and each `key` must be
  unique in the batch. An invalid batch is refused with `400` before any job is created or billed.
  See [batch text moderation](/moderation/text-moderation#batch-text-moderation).
</Note>

One batch request counts as one request against your [rate limit](/platform/rate-limiting). Each
item is billed as one text moderation job.


## OpenAPI

````yaml api-reference/openapi.json POST /api/v1/moderate/text/batch
openapi: 3.1.0
info:
  title: Omnifence API
  description: >-
    Content moderation API. Clients submit images or videos which pass through a
    classification pipeline and receive a pass/reject decision.
  version: 1.0.0
  contact:
    email: support@omnifence.ai
servers:
  - url: http://localhost:3051
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Moderation
    description: Submit moderation jobs
  - name: Jobs
    description: Query job status and progress
  - name: Webhooks
    description: Webhook registration
  - name: Shared Registry
    description: >-
      Cross-platform banned-user registry for vetted members (requires
      registry:check or registry:submit)
  - name: Account
    description: Authenticated client account settings
paths:
  /api/v1/moderate/text/batch:
    post:
      tags:
        - Moderation
      summary: Submit a text moderation batch
      description: >-
        Submit 1 to 99 texts in one request. Each item is checked on its own,
        exactly as `/moderate/text` checks one text, and gets its own decision
        under the `key` you gave it. One batch request counts as one request
        against your rate limit; each item is billed as one text moderation.
        Each item is also an ordinary text job, so `GET /job/{job_id}` reads it.
        When every item has a final decision or has failed, one webhook carries
        all the decisions. The batch is accepted whole or refused whole: an
        empty batch (`BATCH_EMPTY`), more than 99 items (`BATCH_TOO_LARGE`), a
        repeated key (`DUPLICATE_ITEM_KEY`), a text over 20,000 characters
        (`TEXT_TOO_LONG`) or any other invalid item (`INVALID_REQUEST`) refuses
        the request with 400, and nothing is charged.
      operationId: submitTextModerationBatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                items:
                  type: array
                  minItems: 1
                  maxItems: 99
                  description: >-
                    The texts to check, 1 to 99. Each item is checked on its own
                    and gets its own decision.
                  items:
                    type: object
                    properties:
                      key:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: ^[A-Za-z0-9_.:-]+$
                        description: >-
                          Your name for this item, unique in the batch, for
                          example `backstory`. The decision for the item carries
                          the same key.
                      text:
                        type: string
                        minLength: 1
                        maxLength: 20000
                        description: >-
                          The text to check. At most 20,000 characters, as for
                          `/moderate/text`.
                    required:
                      - key
                      - text
                webhook_url:
                  type: string
                  format: uri
                  description: >-
                    HTTPS URL that receives one webhook when every item has a
                    final decision or has failed. Falls back to your registered
                    webhook. Items send no webhook of their own.
              required:
                - items
      responses:
        '202':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  batch_id:
                    type: string
                    format: uuid
                  status:
                    type: string
                    enum:
                      - processing
                  items:
                    type: array
                    description: >-
                      One entry for each submitted item, in the order you sent
                      them.
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                        job_id:
                          type: string
                          format: uuid
                          description: >-
                            The item is an ordinary text job: `GET
                            /job/{job_id}` reads it.
                      required:
                        - key
                        - job_id
                required:
                  - batch_id
                  - status
                  - items
        '503':
          description: >-
            Moderation intake is busy or a dependency is unavailable. Capacity
            rejections include Retry-After (seconds); retry with backoff and
            jitter. SUBMISSION_STATUS_UNKNOWN includes a batch_id: read it with
            GET /moderate/text/batch/{batch_id} before submitting again, because
            acceptance could not be confirmed.
          content:
            application/json:
              schema:
                description: >-
                  Moderation intake is busy or a dependency is unavailable.
                  Capacity rejections include Retry-After (seconds); retry with
                  backoff and jitter. SUBMISSION_STATUS_UNKNOWN includes a
                  batch_id: read it with GET /moderate/text/batch/{batch_id}
                  before submitting again, because acceptance could not be
                  confirmed.
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                  statusCode:
                    type: integer
                    enum:
                      - 503
                  batch_id:
                    type: string
                    format: uuid
                    description: Recovery ID when the acceptance outcome is unknown.
                required:
                  - error
                  - message
                  - statusCode
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl -X POST https://api.omnifence.ai/api/v1/moderate/text/batch \
              -H "Authorization: Bearer $OMNIFENCE_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "items": [
                  { "key": "name", "text": "Captain Mira" },
                  { "key": "backstory", "text": "A pilot who left the fleet." }
                ],
                "webhook_url": "https://your-app.com/webhooks/omnifence"
              }'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key from the Omnifence dashboard

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.