# Moderate Text

> Scan and moderate text for unsafe or policy-relevant material across 10+ categories with the Text Moderation API.

The Copyleaks [Text Moderation](https://copyleaks.com/text-moderation) API empowers you to build safer online environments by proactively identifying and flagging harmful or risky content in real-time. With support for a broad range of categories-including hate speech, toxic language, and more-our API provides the tools you need to enforce your community standards effectively.

This guide will walk you through submitting text for moderation and building a robust workflow based on the results.

## Get started

<Steps>
  <Step>
    ### Before you begin
    Before you start, ensure you have the following:
    - An active Copyleaks account. If you don't have one, **[sign up for free](https://api.copyleaks.com/signup)**.
    - You can find your API key on the **[API Dashboard](https://api.copyleaks.com/dashboard)**.
  </Step>

  <Step>
    ### Installation
    <InstallSDKs />
  </Step>

  <Step>
    ### Login
    <GuideLogin />
  </Step>

  <Step>
    ### Submit for moderation
    Use the [Text Moderation Endpoint](/reference/actions/text-moderation/check). Provide a unique `scanId` for each request.

    <Tip>
      For testing, set `"sandbox": true`. Sandbox mode is free and returns mock results.
    </Tip>

    <CodeGroup>
      ```http title="HTTP" icon="globe"
      POST https://api.copyleaks.com/v1/text-moderation/my-scan-1/check
      Authorization: Bearer <YOUR_AUTH_TOKEN>
      Content-Type: application/json

      {
        "text": "Your text content to be moderated goes here.",
        "sandbox": true,
        "language": "en",
        "labels": [
          { "id": "toxic-v1" },
          { "id": "profanity-v1" },
          { "id": "hate-speech-v1" }
        ]
      }
      ```
      ```bash title="cURL" icon="terminal"
      curl -X POST "https://api.copyleaks.com/v1/text-moderation/my-scan-1/check" \
           -H "Authorization: Bearer <YOUR_AUTH_TOKEN>" \
           -H "Content-Type: application/json" \
           -d '{
                 "text": "Your text content to be moderated goes here.",
                 "sandbox": true,
                 "language": "en",
                 "labels": [
                   { "id": "toxic-v1" },
                   { "id": "profanity-v1" },
                   { "id": "hate-speech-v1" }
                 ]
               }'
      ```
      ```python title="Python" icon="python"
      from copyleaks.copyleaks import Copyleaks
      from copyleaks.models.TextModeration.Requests.CopyleaksTextModerationRequestModel import CopyleaksTextModerationRequestModel

      scan_id = "my-moderation-scan"
      model = CopyleaksTextModerationRequestModel(
          text="This is some text to scan.",
          sandbox=True,
          language="en",
          labels=[
              {"id": "other-v1"},
              {"id": "adult-v1"},
              {"id": "toxic-v1"},
              {"id": "violent-v1"},
              {"id": "profanity-v1"},
              {"id": "self-harm-v1"},
              {"id": "harassment-v1"},
              {"id": "hate-speech-v1"},
              {"id": "drugs-v1"},
              {"id": "firearms-v1"},
              {"id": "cybersecurity-v1"},
          ]
      )
      textModerationResponse = Copyleaks.TextModerationClient.submit_text(auth_token, scan_id, model)
      print("Text Moderation"+ "\n")
      print(textModerationResponse.model_dump_json())
      ```
      ```javascript title="JavaScript" icon="square-js"
      const { Copyleaks, CopyleaksTextModerationRequestModel } = require('plagiarism-checker');

      async function moderateText() {
          try {
              // Initialize Copyleaks
              const copyleaks = new Copyleaks();

              // Login to get the authentication token.
              // Replace with your email and API key.
              const loginResult = await copyleaks.loginAsync('YOUR_EMAIL@example.com', 'YOUR_API_KEY');

              const scanId = `moderation-scan-${Date.now()}`;
              
              // The text to be moderated
              const textToModerate = "This is some text to scan for harmful content.";

              // Create a moderation request model
              const submission = new CopyleaksTextModerationRequestModel({
                  text: textToModerate,
                  sandbox: true, // Use sandbox for testing
                  language: 'en',
                  labels: [
                      { id: "toxic-v1" },
                      { id: "profanity-v1" },
                      { id: "hate-speech-v1" }
                  ]
              });

              // Submit the text for moderation
              const response = await copyleaks.textModerationClient.submitTextAsync(loginResult, scanId, submission);
              console.log("Moderation results:", response);

          } catch (error) {
              console.error("An error occurred:", error);
          }
      }

      moderateText();
      ```
      ```java title="Java" icon="java"
      import classes.Copyleaks;
      import models.submissions.CopyleaksTextModerationModel;
      import models.submissions.properties.ModerationLabel;
      import models.responses.ModerationResponse;
      import java.util.Arrays;

      String scanId = "my-moderation-scan";
      String sampleText = "Your text content to be moderated goes here.";

      CopyleaksTextModerationModel submission = new CopyleaksTextModerationModel(
          sampleText,
          Arrays.asList(new ModerationLabel("toxic-v1"), new ModerationLabel("profanity-v1")),
          "en",
          true // sandbox
      );
      
      ModerationResponse response = Copyleaks.moderateText(authToken, scanId, submission);
      System.out.println(response);
      ```
    </CodeGroup>
  </Step>

  <Step>
    ### Interpreting the response
    The API returns a `legend` array that maps [labels](/reference/data-types/moderation/text-moderation-labels) IDs to numerical indices, and a `moderations` object that pinpoints the exact location of flagged content using those indices.

    -   **`legend`**: A lookup table where each `id` (e.g., "toxic-v1") corresponds to an `index`.
    -   **`moderations.text.chars`**: Contains parallel arrays:
        -   `starts`: An array of starting character positions for each flagged segment.
        -   `lengths`: An array of character lengths for each segment.
        -   `labels`: An array of numerical indices that correspond to the `legend`.

    ```json title="Example Response"
    {
      "moderations": {
        "text": {
          "chars": {
            "labels": [ 2, 4 ],
            "starts": [ 27, 100 ],
            "lengths": [ 2, 8 ]
          }
        }
      },
      "legend": [
        { "index": 2, "id": "toxic-v1" },
        { "index": 4, "id": "profanity-v1" }
      ],
      "modelVersion": "v1",
      "scannedDocument": {
          "scanId": "test",
          "totalWords": 479,
          "totalExcluded": 0,
          "actualCredits": 2,
          "expectedCredits": 2,
          "creationTime": "2025-08-13T06:51:29.4899318Z"
      }
    }
    ```
    In this example, the content is flagged for "toxic-v1" starting at character 27 and for "profanity-v1" starting at character 100.
  </Step>

  <Step>
    ### Summary
    You have successfully submitted text for moderation. You can now use the JSON response in your application to take further actions based on the findings.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
    <Card title="Moderation Labels" icon="tags" href="/reference/data-types/moderation/text-moderation-labels/">See a complete list of all supported content moderation labels and their descriptions.</Card>
    <Card title="Full API Reference" icon="code" href="/reference/actions/text-moderation/check/">Explore the complete documentation for the Text Moderation endpoint and response object.</Card>
    <Card title="Try it" icon="play" href="https://copyleaks.com/text-moderation">See how Copyleaks text moderation flags unsafe content with your own examples.</Card>
</CardGroup>
