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

# Moderation API

> Kiểm tra prompt và hình ảnh trước khi sản phẩm AI của bạn tạo nội dung, đồng thời nhận kết quả cho phép, gắn cờ hoặc từ chối kèm điểm số cho 17 danh mục nội dung.

<CardGroup cols={2}>
  <Card title="Screen a Prompt" icon="shield-check" href="/api-reference/moderation/screen">
    Gửi văn bản, hình ảnh hoặc cả hai, rồi nhận kết quả.
  </Card>

  <Card title="Get Moderation Usage" icon="chart-column" href="/api-reference/moderation/get-usage">
    Xem số lượt kiểm tra tính phí và khoản phí tiếp theo của bạn.
  </Card>
</CardGroup>

## Tổng quan

Moderation API kiểm tra dữ liệu đầu vào của người dùng trước khi sản phẩm AI của bạn tạo nội dung từ dữ liệu đó. Bạn gửi văn bản của prompt, một hình ảnh hoặc cả hai, và Dodo Payments trả về kết quả `allow`, `flag` hoặc `deny`, cùng với điểm số cho từng danh mục nội dung.

Sử dụng API này trước bất kỳ model tạo hình ảnh, video hoặc văn bản nào nhận dữ liệu đầu vào từ người dùng. Theo mặc định, Moderation API được bật cho mọi doanh nghiệp và hoạt động với API key Dodo Payments hiện có của bạn, vì vậy bạn không cần đăng ký thêm. Dodo Payments có thể tắt API này cho một doanh nghiệp cụ thể; khi đó, các lệnh gọi sẽ trả về `403` cùng với `MODERATION_DISABLED`.

## Vì sao chúng tôi xây dựng Moderation API

Sản phẩm tạo nội dung bằng AI tạo ra nội dung mới từ bất kỳ điều gì người dùng nhập. Bạn không thể tự kiểm tra từng prompt, và chỉ một kết quả có hại cũng có thể khiến doanh nghiệp của bạn gặp rủi ro.

Với vai trò Merchant of Record của bạn, Dodo Payments chịu trách nhiệm pháp lý và danh tiếng đối với những gì được bán trên nền tảng. [Merchant Acceptance Policy](/miscellaneous/merchant-acceptance) xem xét các công cụ tạo nội dung bằng AI và không cho phép hành vi mạo danh, deepfake hoặc nội dung khiêu dâm, bao gồm cả nội dung do AI tạo. Tài khoản tạo nội dung có hại, có quá nhiều chargeback hoặc nhận cờ từ các đối tác thanh toán có thể bị xem xét hoặc đình chỉ.

Chúng tôi xây dựng Moderation API để bạn có thể ngăn nội dung này trước khi model tạo ra nội dung đó:

* **Kiểm tra trước khi tạo.** Prompt bị chặn sẽ không bao giờ đến được model của bạn, vì vậy không tạo ra kết quả có hại và bạn không tốn tài nguyên tính toán cho prompt đó.
* **Bao quát các danh mục quan trọng đối với việc tạo nội dung.** Bộ kiểm tra chấm điểm 17 danh mục, bao gồm hình ảnh giống người thật, hình ảnh thân mật không có sự đồng thuận, ngôn ngữ ám chỉ người chưa thành niên và sự kết hợp giữa người thật với nội dung tình dục, vốn là dấu hiệu của deepfake tình dục.
* **Tích hợp mà không cần nhà cung cấp khác.** API hoạt động với API key Dodo Payments của bạn và phí được khấu trừ từ số dư. Không có hợp đồng, hóa đơn hoặc tài khoản riêng.
* **Bảo mật nội dung người dùng.** Dodo Payments không lưu trữ hoặc ghi log văn bản và hình ảnh bạn kiểm tra.

<Note>
  Moderation API là công cụ để bạn tự thực thi chính sách. API này không thay thế Merchant Acceptance Policy và bạn vẫn chịu trách nhiệm về nội dung mà sản phẩm tạo ra.
</Note>

## Cách hoạt động

Gọi Moderation API từ backend sau khi người dùng gửi prompt và trước khi model của bạn chạy:

```mermaid theme={null}
flowchart LR
  A[User submits a prompt] --> B[Your backend calls POST /moderation/screen]
  B -->|allow| C[Generate]
  B -->|flag| D[Apply your own policy]
  B -->|deny| E[Block the request]
  B -->|error, no verdict| E
```

Mỗi lệnh gọi là một **lượt kiểm tra**. Văn bản và hình ảnh được gửi trong cùng một lệnh gọi được tính là một lượt kiểm tra.

### Kết quả

Trường `decision` chứa kết quả:

| Kết quả | Ý nghĩa                                                                                      | Việc cần làm                                                                         |
| ------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `allow` | Nội dung đã được chấp thuận.                                                                 | Tạo nội dung.                                                                        |
| `flag`  | Nội dung vượt ngưỡng của một danh mục cần được đánh giá. Đây không phải là từ chối tạm thời. | Áp dụng chính sách riêng của bạn. Bạn có thể chặn, gửi đi xem xét hoặc tạo nội dung. |
| `deny`  | Không được tạo nội dung này.                                                                 | Chặn yêu cầu và hiển thị lỗi cho người dùng.                                         |

<Warning>
  Không tạo nội dung khi bạn không nhận được kết quả. `503` có nghĩa là Dodo Payments không thể đưa ra kết quả, và timeout hoặc lỗi mạng cũng khiến bạn không có kết quả. Hãy xem tất cả các trường hợp này là bị chặn và yêu cầu người dùng thử lại.
</Warning>

## Kiểm tra prompt

Để kiểm tra prompt, gửi yêu cầu `POST` đến `/moderation/screen` với ít nhất một trong hai trường `text` và `image`. Yêu cầu chấp nhận ba trường:

| Trường       | Kiểu   | Mô tả                                                                                                                                                                           |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text`       | string | Văn bản cần kiểm tra, tối đa 8.000 ký tự.                                                                                                                                       |
| `image`      | string | Hình ảnh cần kiểm tra ở dạng base64, có hoặc không có tiền tố `data:image/...;base64,`.                                                                                         |
| `request_id` | string | Tùy chọn. Mã định danh của bạn cho lượt kiểm tra này, chẳng hạn như generation ID, tối đa 128 ký tự và không chứa ký tự điều khiển. Phản hồi trả về giá trị này không thay đổi. |

TypeScript và Python SDK cung cấp endpoint dưới dạng `client.moderation.screen()`. Ví dụ này chặn việc tạo nội dung khi nhận `deny`, `flag` hoặc bất kỳ lỗi nào:

<Note>
  Các ví dụ gọi live mode vì chỉ live mode mới chạy moderation model. Test mode trả về [mock verdicts](#testing-your-integration) và không bao giờ kiểm tra nội dung. Lượt kiểm tra trong live mode được tính phí.
</Note>

<CodeGroup>
  ```typescript Node.js expandable theme={null}
  import DodoPayments from 'dodopayments';

  const client = new DodoPayments({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    environment: 'live_mode',
  });

  async function generateImage(prompt: string, generationId: string) {
    let verdict;
    try {
      verdict = await client.moderation.screen({
        text: prompt,
        request_id: generationId,
      });
    } catch (err) {
      // No verdict: do not generate.
      throw new Error('Moderation is unavailable. Try again in a moment.');
    }

    if (verdict.decision !== 'allow') {
      throw new Error('This prompt cannot be generated. Revise it and try again.');
    }

    return myModel.generate(prompt);
  }
  ```

  ```python Python expandable theme={null}
  import os
  from dodopayments import DodoPayments, APIError

  client = DodoPayments(
      bearer_token=os.environ["DODO_PAYMENTS_API_KEY"],
      environment="live_mode",
  )

  def generate_image(prompt: str, generation_id: str):
      try:
          verdict = client.moderation.screen(text=prompt, request_id=generation_id)
      except APIError:
          # No verdict: do not generate.
          raise RuntimeError("Moderation is unavailable. Try again in a moment.")

      if verdict.decision != "allow":
          raise ValueError("This prompt cannot be generated. Revise it and try again.")

      return my_model.generate(prompt)
  ```

  ```bash cURL theme={null}
  curl -X POST https://live.dodopayments.com/moderation/screen \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "text": "a watercolor painting of a lighthouse at sunset",
      "request_id": "gen_7Hc2k9"
    }'
  ```
</CodeGroup>

Ví dụ xem `flag` giống như `deny`. Nếu sản phẩm của bạn cho phép một số nội dung bị gắn cờ, hãy kiểm tra `triggered` để quyết định theo từng danh mục.

<Tip>
  Hãy kiểm tra văn bản do người dùng viết, không phải prompt template mà bạn bọc bên ngoài. Template của riêng bạn giống nhau trong mọi lệnh gọi và không bổ sung gì cho lượt kiểm tra.
</Tip>

### Kiểm tra hình ảnh

Gửi hình ảnh để kiểm tra hình ảnh tham chiếu được tải lên hoặc hình ảnh được tạo trước khi hiển thị cho người dùng. Hình ảnh phải đáp ứng các yêu cầu sau:

* Định dạng là JPEG, PNG, WebP, GIF hoặc BMP.
* Chuỗi base64 có tối đa 6.991.530 ký tự và hình ảnh sau khi giải mã có kích thước tối đa 5 MiB.
* Hình ảnh là một khung hình tĩnh duy nhất. Hình ảnh GIF và WebP động sẽ bị từ chối.
* Cạnh dài nhất có ít nhất 32 pixel.

Hình ảnh không vượt qua một trong các bước kiểm tra này sẽ trả về `400` với `MODERATION_INVALID_IMAGE`, hoặc `413` với `MODERATION_INPUT_TOO_LARGE` khi hình ảnh quá lớn.

Để kiểm tra hình ảnh, đọc tệp, mã hóa tệp dưới dạng base64 và gửi trong `image`. Để kiểm tra hình ảnh cùng prompt, gửi cả `text` và `image` trong cùng một lệnh gọi. Lượt này được tính là một lượt kiểm tra. Ví dụ này sử dụng `client` từ ví dụ trước:

<CodeGroup>
  ```typescript Node.js expandable theme={null}
  import { readFile } from 'node:fs/promises';

  async function screenImage(path: string, prompt: string, generationId: string) {
    const image = (await readFile(path)).toString('base64');

    const verdict = await client.moderation.screen({
      image, // or `data:image/png;base64,${image}`
      text: prompt, // optional: screen the prompt with the image
      request_id: generationId,
    });

    return verdict.decision === 'allow';
  }
  ```

  ```python Python expandable theme={null}
  import base64

  def screen_image(path: str, prompt: str, generation_id: str) -> bool:
      with open(path, "rb") as f:
          image = base64.b64encode(f.read()).decode("ascii")

      verdict = client.moderation.screen(
          image=image,  # or f"data:image/png;base64,{image}"
          text=prompt,  # optional: screen the prompt with the image
          request_id=generation_id,
      )
      return verdict.decision == "allow"
  ```

  ```bash cURL expandable theme={null}
  # Builds the JSON body with jq, so a large image does not hit the shell argument limit.
  base64 < reference.png | tr -d '\n' \
    | jq -Rs '{image: ., text: "turn this photo into a watercolor painting", request_id: "gen_7Hc2k9"}' \
    | curl -X POST https://live.dodopayments.com/moderation/screen \
        -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY" \
        -H "Content-Type: application/json" \
        --data @-
  ```
</CodeGroup>

Xử lý lỗi từ lượt kiểm tra hình ảnh giống như lượt kiểm tra văn bản: nếu lệnh gọi phát sinh lỗi, không tạo nội dung.

## Đọc phản hồi

Phản hồi trả về kết quả và bằng chứng phía sau kết quả đó:

| Trường               | Mô tả                                                                                                                                      |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `decision`           | Kết quả: `allow`, `flag` hoặc `deny`.                                                                                                      |
| `triggered`          | Các danh mục có điểm số vượt ngưỡng của danh mục đó. Trường này có thể trống đối với `flag` từ bước kiểm tra tổng quát.                    |
| `compound_triggered` | `true` khi hình ảnh giống người thật và nội dung tình dục cùng vượt ngưỡng kết hợp, tạo thành dấu hiệu của deepfake tình dục.              |
| `categories`         | Xác suất từ 0 đến 1 cho biết nội dung thuộc từng danh mục.                                                                                 |
| `provenance`         | Cách đo từng điểm số: `targeted` bằng bước kiểm tra riêng cho danh mục đó hoặc `broad` bằng bước kiểm tra tổng quát bao quát mọi danh mục. |
| `notes`              | Lý do dễ đọc đối với quyết định. Cách diễn đạt có thể thay đổi, vì vậy không phân tích trường này.                                         |
| `normalized_applied` | `true` khi văn bản cũng được kiểm tra sau khi loại bỏ kỹ thuật làm rối, chẳng hạn như ký tự vô hình hoặc ký tự trông giống nhau.           |
| `passes`             | Số câu hỏi có/không mà model đã trả lời cho lượt kiểm tra này.                                                                             |
| `latency_ms`         | Thời gian thực hiện lượt kiểm tra, tính bằng mili giây.                                                                                    |
| `request_id`         | `request_id` bạn đã gửi hoặc `null`.                                                                                                       |

Dựa trên logic của bạn vào `decision` và `triggered`. Mỗi danh mục có ngưỡng riêng, vì vậy một ngưỡng điểm duy nhất trong code sẽ không khớp với kết quả.

### Danh mục

Mỗi phản hồi chấm điểm nội dung theo 17 danh mục:

| Danh mục                          | Bao gồm                                                              |
| --------------------------------- | -------------------------------------------------------------------- |
| `violent_crimes`                  | Tội phạm bạo lực.                                                    |
| `sex_related_crimes`              | Tội phạm liên quan đến tình dục.                                     |
| `child_sexual_exploitation`       | Bóc lột tình dục trẻ em.                                             |
| `suicide_and_self_harm`           | Tự sát và tự gây thương tích.                                        |
| `indiscriminate_weapons`          | Vũ khí hóa học, sinh học, phóng xạ, hạt nhân hoặc chất nổ.           |
| `intellectual_property`           | Vi phạm bản quyền hoặc nhãn hiệu.                                    |
| `defamation`                      | Mô tả sai sự thật có khả năng làm tổn hại danh tiếng của người thật. |
| `non_violent_crimes`              | Tội phạm không bạo lực.                                              |
| `hate`                            | Hạ thấp người khác vì một đặc điểm được pháp luật bảo vệ.            |
| `privacy`                         | Thông tin riêng tư nhạy cảm về một người.                            |
| `specialized_advice`              | Tư vấn tài chính, y tế, pháp lý hoặc bầu cử không đủ điều kiện.      |
| `sexual_content`                  | Nội dung khiêu dâm hoặc mô tả tình dục rõ ràng.                      |
| `non_consensual_intimate_imagery` | Cởi quần áo, khỏa thân hóa hoặc tình dục hóa một người thật.         |
| `minor_coded_language`            | Ngôn ngữ ám chỉ độ tuổi cho thấy đối tượng là người chưa thành niên. |
| `real_person_likeness`            | Hình ảnh giống một người thật, có thể nhận dạng và được nêu tên.     |
| `living_artist_style`             | Bắt chước phong cách đặc trưng của một nghệ sĩ cụ thể đang còn sống. |
| `prompt_injection`                | Nỗ lực ghi đè hoặc thao túng hướng dẫn của hệ thống.                 |

## Xử lý lỗi

Lỗi trả về phần nội dung lỗi tiêu chuẩn của Dodo Payments cùng với `code` và `message`. Không lỗi nào là kết quả, vì vậy không lỗi nào cho phép tạo nội dung:

| Trạng thái | `code`                       | Nguyên nhân                                                                            | Việc cần làm                                        |
| ---------- | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `400`      | `INVALID_REQUEST_PARAMETERS` | Yêu cầu không đúng định dạng hoặc không có `text` cũng như `image`.                    | Sửa yêu cầu.                                        |
| `400`      | `MODERATION_INVALID_IMAGE`   | Không thể giải mã hình ảnh, hình ảnh động hoặc quá nhỏ.                                | Gửi hình ảnh tĩnh được hỗ trợ.                      |
| `403`      | `MODERATION_DISABLED`        | Dodo Payments đã tắt Moderation API cho doanh nghiệp của bạn.                          | Liên hệ bộ phận hỗ trợ để biết lý do.               |
| `413`      | `MODERATION_INPUT_TOO_LARGE` | `text` dài hơn 8.000 ký tự hoặc `image` vượt quá giới hạn kích thước.                  | Rút ngắn văn bản hoặc giảm kích thước hình ảnh.     |
| `429`      | `MODERATION_OVERLOADED`      | Moderation đã đạt giới hạn công suất. Đây là giới hạn thông lượng, không phải kết quả. | Chờ số giây trong header `Retry-After` rồi thử lại. |
| `503`      | `MODERATION_UNAVAILABLE`     | Không có kết quả.                                                                      | Không tạo nội dung. Thử lại sau.                    |

SDK mặc định thử lại `429` hoặc `503` hai lần và chờ `Retry-After` giữa các lần thử. Khi hết số lần thử, SDK sẽ phát sinh lỗi và code của bạn phải chặn yêu cầu.

## Kiểm thử tích hợp

Test mode trả về kết quả mô phỏng và không bao giờ gọi moderation model, vì vậy bạn có thể kiểm thử luồng xử lý mà không mất phí. Gửi yêu cầu đến `https://test.dodopayments.com` bằng API key của test mode.

Kết quả mô phỏng mặc định là `allow`. Để nhận kết quả khác, đặt một trong các chuỗi sau ở bất kỳ vị trí nào trong `text`:

| Chuỗi trong `text`     | Phản hồi                                           |
| ---------------------- | -------------------------------------------------- |
| `dodo_mock_flag`       | `200` với `decision` được đặt thành `flag`         |
| `dodo_mock_deny`       | `200` với `decision` được đặt thành `deny`         |
| `dodo_mock_overloaded` | `429` `MODERATION_OVERLOADED` với `Retry-After: 1` |
| `dodo_mock_not_ready`  | `503` `MODERATION_UNAVAILABLE`                     |

Kết quả mô phỏng có ghi chú cho biết đó là kết quả mô phỏng và tất cả điểm số danh mục đều là `0`. Test mode áp dụng cùng quy trình xác thực yêu cầu như live mode. Đối với hình ảnh, chế độ này kiểm tra encoding base64 và định dạng, nhưng không kiểm tra số khung hình hoặc kích thước.

Trước khi chuyển sang live mode, hãy xác nhận tích hợp của bạn xử lý từng trường hợp sau:

<Steps>
  <Step title="Deny Blocks Generation">
    Gửi `dodo_mock_deny` và xác nhận model của bạn không được gọi.
  </Step>

  <Step title="Flag Follows Your Policy">
    Gửi `dodo_mock_flag` và xác nhận sản phẩm của bạn thực hiện đúng chính sách.
  </Step>

  <Step title="Overload Retries">
    Gửi `dodo_mock_overloaded` và xác nhận code chờ `Retry-After` cũng như không tạo nội dung khi chưa có kết quả.
  </Step>

  <Step title="An Outage Blocks Generation">
    Gửi `dodo_mock_not_ready` và xác nhận model của bạn không được gọi.
  </Step>

  <Step title="Every Generation Path Screens">
    Kiểm tra để bảo đảm mọi luồng code dẫn đến model đều gọi Moderation API trước.
  </Step>
</Steps>

## Định giá và tính phí

Moderation API có giá **0,30 USD cho mỗi 1.000 lượt kiểm tra tính phí**. Không có gói miễn phí và không có mức tối thiểu.

Lượt kiểm tra tính phí là lượt kiểm tra trong live mode trả về kết quả. Các lượt sau được miễn phí và không được tính:

* Lượt kiểm tra trong test mode.
* Lượt kiểm tra trả về lỗi, bao gồm `429` và `503`.

Dodo Payments tính phí theo các khối đủ 1.000 lượt kiểm tra. Mỗi khối hoàn chỉnh được tính phí trong vòng một giờ, còn các lượt chưa đủ một khối sẽ chưa bị tính phí cho đến khi đủ. Phí được khấu trừ từ số dư USD của bạn và xuất hiện trong [balance ledger](/api-reference/balance-ledger/list-ledger-entries) với event type `moderation_fees`. Payouts hiển thị khoản phí này dưới **Moderation Fees**.

### Theo dõi mức sử dụng

Để xem mức sử dụng, gọi `GET /moderation/usage`. Phản hồi trả về:

| Trường                  | Mô tả                                                                                                                         |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `unbilled_screens`      | Các lượt kiểm tra tính phí mà Dodo Payments chưa tính phí.                                                                    |
| `screens_to_next_block` | Số lượt kiểm tra tính phí còn cần để đủ khối 1.000 lượt tiếp theo.                                                            |
| `daily`                 | Số lượt kiểm tra tính phí của bạn theo từng ngày UTC trong 30 ngày gần nhất. Những ngày không có lượt kiểm tra sẽ bị lược bỏ. |

<CodeGroup>
  ```bash cURL theme={null}
  curl https://live.dodopayments.com/moderation/usage \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY"
  ```

  ```typescript Node.js theme={null}
  const usage = await client.moderation.retrieveUsage();
  console.log(usage.unbilled_screens, usage.screens_to_next_block);
  ```

  ```python Python theme={null}
  usage = client.moderation.retrieve_usage()
  print(usage.unbilled_screens, usage.screens_to_next_block)
  ```
</CodeGroup>

Test mode không ghi nhận lượt kiểm tra, vì vậy usage endpoint không trả về hoạt động nào của test mode.

## Quyền truy cập và quyền riêng tư

Việc kiểm tra yêu cầu API key có quyền ghi. Mọi API key, bao gồm key chỉ đọc, đều có thể đọc mức sử dụng. Xem [Authentication](/api-reference/introduction#authentication) để biết cách tạo key và đặt cấp độ truy cập.

Dodo Payments không lưu trữ văn bản hoặc hình ảnh bạn kiểm tra và không ghi chúng vào log. Với mỗi lượt kiểm tra trong live mode, hệ thống lưu thời gian, kết quả và `request_id` của bạn để báo cáo tính phí và mức sử dụng.

<CardGroup cols={2}>
  <Card title="Usage-Based Billing" icon="arrow-trend-up" href="/features/usage-based-billing/introduction">
    Tính phí khách hàng của bạn cho mỗi lần tạo nội dung.
  </Card>

  <Card title="Credit-Based Billing" icon="coins" href="/features/credit-based-billing">
    Bán credit tạo nội dung và khấu trừ credit theo mỗi lần sử dụng.
  </Card>
</CardGroup>
