> ## 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

> AI製品が生成する前にプロンプトと画像をスクリーニングし、17のコンテンツカテゴリごとのスコアとともに、許可、フラグ、拒否の判定を取得します。

<CardGroup cols={2}>
  <Card title="Screen a Prompt" icon="shield-check" href="/api-reference/moderation/screen">
    テキスト、画像、またはその両方を送信して、判定を取得します。
  </Card>

  <Card title="Get Moderation Usage" icon="chart-column" href="/api-reference/moderation/get-usage">
    課金対象のスクリーン数と次回の請求額を確認します。
  </Card>
</CardGroup>

## 概要

Moderation APIは、AI製品がユーザー入力をもとに生成する前に、その入力をスクリーニングします。プロンプトのテキスト、画像、またはその両方を送信すると、Dodo Paymentsは各コンテンツカテゴリのスコアとともに、`allow`、`flag`、または`deny`の判定を返します。

ユーザーからの入力を受け取る画像、動画、またはテキスト生成モデルの前段で利用できます。Moderation APIはデフォルトですべてのビジネスに対して有効で、既存のDodo Payments API keyで実行されるため、登録は必要ありません。Dodo Paymentsは個別のビジネスに対して無効化でき、その場合、呼び出しは`403`と`MODERATION_DISABLED`を返します。

## Moderation APIを構築した理由

AI生成製品は、ユーザーが入力した内容をもとに新しいコンテンツを作成します。すべてのプロンプトを手作業で確認することはできず、有害な出力が1つあるだけでもビジネスがリスクにさらされる可能性があります。

Merchant of Recordとして、Dodo Paymentsはプラットフォームを通じて販売されるものについて、法的および評判上の責任を負います。[Merchant Acceptance Policy](/miscellaneous/merchant-acceptance)ではAIコンテンツ生成ツールを審査しており、AI生成コンテンツを含む、なりすまし、ディープフェイク、露骨なコンテンツを許可していません。有害なコンテンツ、過度なチャージバック、または決済パートナーからのフラグを生成するアカウントは、審査または停止の対象となる場合があります。

モデルがコンテンツを作成する前に停止できるよう、Moderation APIを構築しました。

* **生成前にスクリーニングする。** ブロックされたプロンプトはモデルに到達しないため、有害な出力は生成されず、そのためのコンピュートも消費しません。
* **生成に重要なカテゴリをカバーする。** スクリーニングでは17のカテゴリをスコアリングします。実在人物の肖像、同意のない性的画像、未成年を示唆する表現、実在人物と性的コンテンツの組み合わせによる性的ディープフェイクなどが含まれます。
* **別のベンダーなしで統合する。** APIはDodo Payments API keyで実行され、料金は残高から引き落とされます。別の契約、請求書、アカウントは必要ありません。
* **ユーザーコンテンツを非公開に保つ。** Dodo Paymentsはスクリーニングしたテキストや画像を保存またはログ記録しません。

<Note>
  Moderation APIは、独自の取り締まりを行うためのツールです。Merchant Acceptance Policyに代わるものではなく、製品が生成するものについては引き続きお客様が責任を負います。
</Note>

## 仕組み

ユーザーがプロンプトを送信した後、モデルを実行する前に、バックエンドからModeration APIを呼び出します。

```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
```

各呼び出しは1つの**スクリーン**です。同じ呼び出しで送信されたテキストと画像は、1つのスクリーンとしてカウントされます。

### 判定

`decision`フィールドに判定が含まれます。

| 判定      | 意味                                           | 対応                                        |
| ------- | -------------------------------------------- | ----------------------------------------- |
| `allow` | コンテンツは通過しました。                                | 生成します。                                    |
| `flag`  | コンテンツが、判断を必要とするカテゴリのしきい値を超えました。ソフト拒否ではありません。 | 独自のポリシーを適用します。ブロック、審査への送信、生成のいずれかを実行できます。 |
| `deny`  | コンテンツを生成してはいけません。                            | リクエストをブロックし、ユーザーにエラーを表示します。               |

<Warning>
  判定を受け取らなかった場合は生成しないでください。`503`は、Dodo Paymentsが判定を生成できなかったことを意味します。また、タイムアウトやネットワークエラーが発生した場合も判定は得られません。これらはすべてブロックとして扱い、ユーザーにもう一度試すよう求めてください。
</Warning>

## プロンプトのスクリーニング

プロンプトをスクリーニングするには、`POST`リクエストを`/moderation/screen`に送信し、`text`または`image`の少なくとも一方を含めます。リクエストでは3つのフィールドを受け付けます。

| フィールド        | 型      | 説明                                                                               |
| ------------ | ------ | -------------------------------------------------------------------------------- |
| `text`       | string | スクリーニングするテキスト。最大8,000文字です。                                                       |
| `image`      | string | base64形式のスクリーニング対象画像。`data:image/...;base64,`プレフィックスの有無は問いません。                   |
| `request_id` | string | 任意。このスクリーンを識別するためのIDです。generation IDなどを指定でき、制御文字を含まない最大128文字です。レスポンスではそのまま返されます。 |

TypeScriptおよびPython SDKでは、エンドポイントを`client.moderation.screen()`として提供しています。この例では、`deny`、`flag`、およびすべてのエラーで生成をブロックします。

<Note>
  例ではlive modeを呼び出しています。moderation modelが実行されるのはlive modeのみだからです。Test modeは[モック判定](#testing-your-integration)を返し、コンテンツのスクリーニングは行いません。live modeのスクリーンは課金対象です。
</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>

この例では`flag`を`deny`と同様に扱います。製品で一部のフラグ付きコンテンツを許可する場合は、`triggered`を確認してカテゴリごとに判断してください。

<Tip>
  ユーザーが入力したテキストをスクリーニングし、その周囲に追加するプロンプトテンプレートは対象にしないでください。独自のテンプレートはすべての呼び出しで同じであり、スクリーンに何も追加しません。
</Tip>

### 画像のスクリーニング

アップロードされた参照画像、または生成後に表示する前の画像をスクリーニングするには、画像を送信します。画像は次の要件を満たす必要があります。

* 形式はJPEG、PNG、WebP、GIF、またはBMPです。
* base64文字列は最大6,991,530文字で、デコード後の画像は最大5 MiBです。
* 画像は単一の静止フレームです。アニメーションGIFおよびWebP画像は拒否されます。
* 長い辺が32ピクセル以上です。

これらのチェックのいずれかに失敗した画像は、`MODERATION_INVALID_IMAGE`を伴う`400`、またはサイズが大きすぎる場合は`MODERATION_INPUT_TOO_LARGE`を伴う`413`を返します。

画像をスクリーニングするには、ファイルを読み取り、base64としてエンコードし、`image`で送信します。画像とそのプロンプトを同時にスクリーニングするには、同じ呼び出しで`text`と`image`の両方を送信します。これは1つのスクリーンとしてカウントされます。この例では、前の例の`client`を使用しています。

<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>

画像のスクリーンからのエラーも、テキストのスクリーンと同じ方法で処理します。呼び出しで例外が発生した場合は生成しないでください。

## レスポンスの読み取り

レスポンスには、判定とその根拠が返されます。

| フィールド                | 説明                                                                    |
| -------------------- | --------------------------------------------------------------------- |
| `decision`           | 判定。`allow`、`flag`、または`deny`です。                                        |
| `triggered`          | スコアがカテゴリのしきい値を超えたカテゴリ。一般チェックによる`flag`では空になる場合があります。                   |
| `compound_triggered` | 実在人物の肖像と性的コンテンツが組み合わさって合算しきい値を超えた場合の`true`。性的ディープフェイクのパターンです。         |
| `categories`         | コンテンツが各カテゴリに該当する確率。0から1の範囲です。                                         |
| `provenance`         | 各スコアの測定方法。1つのカテゴリを確認した`targeted`、またはすべてのカテゴリを対象とする一般チェックによる`broad`です。 |
| `notes`              | 判断の人間向けの理由。文言は変更される可能性があるため、解析しないでください。                               |
| `normalized_applied` | 不可視文字や類似文字など、難読化を除去した状態でもテキストをスクリーニングした場合の`true`。                     |
| `passes`             | モデルがこのスクリーンに対して回答したyes/no質問の数。                                        |
| `latency_ms`         | スクリーンにかかった時間（ミリ秒）。                                                    |
| `request_id`         | 送信した`request_id`、または`null`。                                           |

ロジックは`decision`と`triggered`をもとにしてください。カテゴリごとに独自のしきい値があるため、コードで単一のスコアカットオフを使用しても判定とは一致しません。

### カテゴリ

すべてのレスポンスで、コンテンツを17のカテゴリに照らしてスコアリングします。

| カテゴリ                              | 対象                           |
| --------------------------------- | ---------------------------- |
| `violent_crimes`                  | 暴力犯罪。                        |
| `sex_related_crimes`              | 性関連犯罪。                       |
| `child_sexual_exploitation`       | 児童の性的搾取。                     |
| `suicide_and_self_harm`           | 自殺および自傷行為。                   |
| `indiscriminate_weapons`          | 化学兵器、生物兵器、放射性兵器、核兵器、または爆発物。  |
| `intellectual_property`           | 著作権または商標の侵害。                 |
| `defamation`                      | 実在人物の評判を傷つける可能性が高い虚偽の描写。     |
| `non_violent_crimes`              | 非暴力犯罪。                       |
| `hate`                            | 保護される特性を理由とした人々への侮辱。         |
| `privacy`                         | 個人に関する慎重に扱うべき私的情報。           |
| `specialized_advice`              | 資格のない金融、医療、法律、または選挙に関する助言。   |
| `sexual_content`                  | 性的に露骨な、またはポルノのコンテンツ。         |
| `non_consensual_intimate_imagery` | 実在人物の服を脱がせる、裸にする、または性的に扱う行為。 |
| `minor_coded_language`            | 対象が未成年であることを示唆する年齢を示す表現。     |
| `real_person_likeness`            | 実在する、識別可能な、名前のある人物の肖像。       |
| `living_artist_style`             | 特定の存命アーティストの特徴的な作風の模倣。       |
| `prompt_injection`                | システムの指示を上書きまたは操作しようとする試み。    |

## エラー処理

エラーは、`code`と`message`を含む標準のDodo Paymentsエラーボディを返します。エラーは判定ではないため、いずれも生成を許可しません。

| Status | `code`                       | 原因                                               | 対応                                |
| ------ | ---------------------------- | ------------------------------------------------ | --------------------------------- |
| `400`  | `INVALID_REQUEST_PARAMETERS` | リクエストの形式が不正であるか、`text`も`image`も含まれていません。         | リクエストを修正します。                      |
| `400`  | `MODERATION_INVALID_IMAGE`   | 画像をデコードできない、アニメーション画像である、または小さすぎます。              | 対応している静止画像を送信します。                 |
| `403`  | `MODERATION_DISABLED`        | Dodo Paymentsがビジネスに対してModeration APIを無効にしました。    | サポートに連絡して理由を確認します。                |
| `413`  | `MODERATION_INPUT_TOO_LARGE` | `text`が8,000文字を超えているか、`image`がサイズ制限を超えています。      | テキストを短くするか、画像を縮小します。              |
| `429`  | `MODERATION_OVERLOADED`      | Moderationが容量上限に達しています。これはスループット制限であり、判定ではありません。 | `Retry-After`ヘッダーの秒数を待ってから再試行します。 |
| `503`  | `MODERATION_UNAVAILABLE`     | 判定を利用できません。                                      | 生成しないでください。後で再試行します。              |

SDKはデフォルトで`429`または`503`を2回再試行し、試行の間に`Retry-After`の時間待機します。再試行回数を使い切るとSDKはエラーを発生させるため、コードでリクエストをブロックする必要があります。

## 統合のテスト

Test modeはモック判定を返し、moderation modelを呼び出さないため、費用をかけずにルーティングをテストできます。Test mode API keyを使用して、`https://test.dodopayments.com`にリクエストを送信します。

デフォルトのモック判定は`allow`です。別の結果を取得するには、`text`のどこかに次の文字列のいずれかを含めます。

| `text`内の文字列            | レスポンス                                            |
| ---------------------- | ------------------------------------------------ |
| `dodo_mock_flag`       | `decision`が`flag`に設定された`200`                     |
| `dodo_mock_deny`       | `decision`が`deny`に設定された`200`                     |
| `dodo_mock_overloaded` | `Retry-After: 1`を伴う`429` `MODERATION_OVERLOADED` |
| `dodo_mock_not_ready`  | `MODERATION_UNAVAILABLE`を伴う`503`                 |

モック判定にはモックであることを示す注記が含まれ、すべてのカテゴリスコアは`0`です。Test modeではlive modeと同じリクエスト検証が適用されます。画像については、base64エンコードと形式を確認しますが、フレーム数や寸法は確認しません。

live modeに移行する前に、統合が各ケースを処理できることを確認してください。

<Steps>
  <Step title="Deny Blocks Generation">
    `dodo_mock_deny`を送信し、モデルが呼び出されないことを確認します。
  </Step>

  <Step title="Flag Follows Your Policy">
    `dodo_mock_flag`を送信し、製品がポリシーに従って動作することを確認します。
  </Step>

  <Step title="Overload Retries">
    `dodo_mock_overloaded`を送信し、コードが`Retry-After`を待機し、判定なしでは生成しないことを確認します。
  </Step>

  <Step title="An Outage Blocks Generation">
    `dodo_mock_not_ready`を送信し、モデルが呼び出されないことを確認します。
  </Step>

  <Step title="Every Generation Path Screens">
    モデルに到達するすべてのコードパスで、最初にModeration APIが呼び出されることを確認します。
  </Step>
</Steps>

## 料金と請求

Moderation APIの料金は、**課金対象のスクリーン1,000件あたり0.30 USD**です。無料枠や最低料金はありません。

課金対象のスクリーンとは、判定を返すlive modeのスクリーンです。次のスクリーンは無料で、カウントされません。

* Test modeのスクリーン。
* `429`や`503`を含む、エラーを返すスクリーン。

Dodo Paymentsは1,000スクリーン単位で全額請求します。各単位は1時間以内に課金され、単位に満たないスクリーンは満たすまで未請求のままです。料金はUSD残高から引き落とされ、イベントタイプ`moderation_fees`として[残高台帳](/api-reference/balance-ledger/list-ledger-entries)に表示されます。Payoutsでは**Moderation Fees**として表示されます。

### 使用量の追跡

使用量を確認するには、`GET /moderation/usage`を呼び出します。レスポンスには次の内容が返されます。

| フィールド                   | 説明                                           |
| ----------------------- | -------------------------------------------- |
| `unbilled_screens`      | Dodo Paymentsがまだ請求していない課金対象スクリーン。            |
| `screens_to_next_block` | 次の1,000件単位を満たすために必要な、課金対象スクリーンの残りの件数。        |
| `daily`                 | 過去30日間におけるUTC日ごとの課金対象スクリーン。スクリーンがない日は省略されます。 |

<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ではスクリーンが記録されないため、使用量エンドポイントはTest modeのアクティビティを返しません。

## アクセスとプライバシー

スクリーニングにはwrite accessを持つAPI keyが必要です。read-only keyを含むすべてのAPI keyで使用量を読み取れます。キーの作成方法とアクセスレベルの設定方法については、[Authentication](/api-reference/introduction#authentication)を参照してください。

Dodo Paymentsはスクリーニングしたテキストや画像を保存せず、ログにも記録しません。各live modeのスクリーンについて、請求および使用量レポートのために、時刻、判定、およびお客様の`request_id`を保持します。

<CardGroup cols={2}>
  <Card title="Usage-Based Billing" icon="arrow-trend-up" href="/features/usage-based-billing/introduction">
    生成ごとに自分の顧客へ請求します。
  </Card>

  <Card title="Credit-Based Billing" icon="coins" href="/features/credit-based-billing">
    生成クレジットを販売し、使用ごとに差し引きます。
  </Card>
</CardGroup>
