コンテンツにスキップ

Batch API

Batch APIを使用すると、AIエージェントに複数のメッセージを非同期で送信できます。これは、永続的な接続を維持せずに大量のリクエストを効率的に処理するのに最適です。

概要

Batch APIでは以下のことができます:

  • 単一のAPI呼び出しで複数のリクエストを送信
  • バックグラウンドで非同期にリクエストを処理
  • バッチの進捗を追跡し結果を取得
  • バッチ完了時にWebhook通知を受信
  • 進行中のバッチをキャンセル

バッチの作成

非同期処理のためにリクエストのバッチを送信します。

エンドポイント: POST /api/v1/batches

リクエストボディ

フィールド 必須 説明
agent_id UUID はい すべてのリクエストのデフォルトエージェントID(公開バージョンが必要)
requests array はい 処理するリクエストのリスト(1〜1000件)
webhook object いいえ 通知用のWebhook設定

リクエストアイテムスキーマ

requests配列の各アイテム:

フィールド 必須 説明
custom_id string はい 相関キー(最大256文字、バッチ内で一意である必要があります)
message string はい 送信するメッセージ
agent_id UUID いいえ このリクエスト用にエージェントを上書き
external_user_id string いいえ 外部ユーザー識別子
name string いいえ 作成されるチャットの名前(最大256文字)
attached_file_uuids array いいえ 添付ファイルのUUIDリスト
history_id integer いいえ 会話を継続するための既存のチャット履歴ID

Webhook設定

フィールド 必須 説明
url string はい Webhook URL(HTTPSである必要があります)
events array いいえ 通知するイベント:completedfailedcancelled(デフォルト:["completed", "failed"]
secret string いいえ Webhookペイロードの署名用シークレット(最大255文字)

curl -X POST "https://api.codeer.ai/api/v1/batches" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "550e8400-e29b-41d4-a716-446655440000",
    "requests": [
      {
        "custom_id": "req-001",
        "message": "営業時間は何時ですか?",
        "external_user_id": "user_123"
      },
      {
        "custom_id": "req-002",
        "message": "返品の方法を教えてください",
        "external_user_id": "user_456"
      }
    ],
    "webhook": {
      "url": "https://your-server.com/webhooks/codeer",
      "events": ["completed", "failed"],
      "secret": "your-webhook-secret"
    }
  }'

レスポンス

ステータス: 202 Accepted

{
  "data": {
    "id": "batch-uuid-here",
    "status": "in_progress",
    "agent_id": "550e8400-e29b-41d4-a716-446655440000",
    "total_requests": 2,
    "completed_requests": 0,
    "failed_requests": 0,
    "created_at": "2024-01-15T10:30:00Z",
    "completed_at": null,
    "cancelled_at": null
  },
  "message": null,
  "error_code": 0
}

エージェントは公開されている必要があります

デフォルトのagent_idと個別リクエストのagent_idオーバーライドの両方が、公開されているエージェントを参照する必要があります。未公開のエージェントを使用したリクエストは拒否されます。


バッチの一覧取得

ページネーションとオプションのステータスフィルタリングでバッチを取得します。

エンドポイント: GET /api/v1/batches

クエリパラメータ

パラメータ デフォルト 説明
limit integer 50 ページあたりの結果数(最大1000)
offset integer 0 スキップする結果数
status string - ステータスでフィルタリング:in_progresscompletedfailedcancellingcancelled

curl -X GET "https://api.codeer.ai/api/v1/batches?limit=10&status=completed" \
  -H "x-api-key: YOUR_API_KEY"

レスポンス

{
  "data": [
    {
      "id": "batch-uuid-here",
      "status": "completed",
      "agent_id": "550e8400-e29b-41d4-a716-446655440000",
      "total_requests": 100,
      "completed_requests": 98,
      "failed_requests": 2,
      "created_at": "2024-01-15T10:30:00Z",
      "completed_at": "2024-01-15T10:45:00Z",
      "cancelled_at": null
    }
  ],
  "pagination": {
    "limit": 10,
    "offset": 0,
    "total_records": 50,
    "total_pages": 5,
    "current_page": 1,
    "next_page": "https://api.codeer.ai/api/v1/batches?offset=10&limit=10",
    "prev_page": null
  },
  "message": null,
  "error_code": 0
}

バッチの取得

特定のバッチの現在のステータスを取得します。

エンドポイント: GET /api/v1/batches/{batch_id}

パスパラメータ

パラメータ 説明
batch_id UUID バッチID

curl -X GET "https://api.codeer.ai/api/v1/batches/batch-uuid-here" \
  -H "x-api-key: YOUR_API_KEY"

レスポンス

{
  "data": {
    "id": "batch-uuid-here",
    "status": "in_progress",
    "agent_id": "550e8400-e29b-41d4-a716-446655440000",
    "total_requests": 100,
    "completed_requests": 45,
    "failed_requests": 2,
    "created_at": "2024-01-15T10:30:00Z",
    "completed_at": null,
    "cancelled_at": null
  },
  "message": null,
  "error_code": 0
}

バッチステータス値

ステータス 説明
in_progress バッチは処理中です
completed すべてのリクエストが処理されました
failed バッチ処理が失敗しました
cancelling キャンセル処理中です
cancelled バッチはキャンセルされました

バッチ結果の取得

バッチ内の個々のリクエストの結果を取得します。

エンドポイント: GET /api/v1/batches/{batch_id}/results

パスパラメータ

パラメータ 説明
batch_id UUID バッチID

クエリパラメータ

パラメータ デフォルト 説明
limit integer 50 ページあたりの結果数(最大1000)
offset integer 0 スキップする結果数
status string - ステータスでフィルタリング:pendingprocessingsuccessfailed

curl -X GET "https://api.codeer.ai/api/v1/batches/batch-uuid-here/results?status=success" \
  -H "x-api-key: YOUR_API_KEY"

レスポンス

{
  "data": [
    {
      "custom_id": "req-001",
      "status": "success",
      "response_content": "営業時間は月曜日から金曜日の午前9時から午後6時までです。",
      "response_usage": {
        "tool_calls": [
          {
            "model": "gemini-2.5-flash",
            "call_type": "tool_call",
            "total_tokens": 195,
            "prompt_tokens": 150,
            "completion_tokens": 45
          }
        ],
        "total_calls": 1,
        "total_tokens": 195,
        "main_response": null,
        "total_prompt_tokens": 150,
        "total_completion_tokens": 45
      },
      "error_code": null,
      "error_message": null,
      "history_id": 12345,
      "conversation_id": 6789,
      "processed_at": "2024-01-15T10:31:00Z"
    },
    {
      "custom_id": "req-002",
      "status": "failed",
      "response_content": null,
      "response_usage": null,
      "error_code": 500,
      "error_message": "処理中に内部サーバーエラーが発生しました",
      "history_id": null,
      "conversation_id": null,
      "processed_at": "2024-01-15T10:31:05Z"
    }
  ],
  "pagination": { ... },
  "message": null,
  "error_code": 0
}

リクエストステータス値

ステータス 説明
pending リクエストは処理待ちです
processing リクエストは現在処理中です
success リクエストは正常に完了しました
failed リクエストは失敗しました

結果のエラーコード

結果のエラーコードはHTTPセマンティクスに従います:

エラーコード 説明
400 検証エラー(リクエストデータが不正)
408 バッチ処理がタイムアウトし、リクエスト処理前に終了しました
499 バッチがキャンセルされました
500 処理中に内部サーバーエラーが発生

バッチのキャンセル

進行中のバッチをキャンセルします。保留中のリクエストはキャンセルされますが、すでに処理中のリクエストは完了します。

エンドポイント: POST /api/v1/batches/{batch_id}/cancel

パスパラメータ

パラメータ 説明
batch_id UUID バッチID

curl -X POST "https://api.codeer.ai/api/v1/batches/batch-uuid-here/cancel" \
  -H "x-api-key: YOUR_API_KEY"

レスポンス

ステータス: 202 Accepted

{
  "data": {
    "id": "batch-uuid-here",
    "status": "cancelling",
    "agent_id": "550e8400-e29b-41d4-a716-446655440000",
    "total_requests": 100,
    "completed_requests": 45,
    "failed_requests": 2,
    "created_at": "2024-01-15T10:30:00Z",
    "completed_at": null,
    "cancelled_at": null
  },
  "message": null,
  "error_code": 0
}

キャンセル動作

  • ステータスがin_progressのバッチのみキャンセルできます
  • すでにprocessing状態のリクエストは通常通り完了します
  • 保留中のリクエストはエラーコード499で失敗としてマークされます
  • すべての処理中のリクエストが完了すると、バッチステータスはcancellingからcancelledに移行します

Webhooks

設定された場合、WebhookはHTTP POSTリクエストとして指定されたURLに送信されます。

Webhookペイロード

{
  "event": "batch.completed",
  "timestamp": "2024-01-15T10:45:00Z",
  "data": {
    "id": "batch-uuid-here",
    "status": "completed",
    "total_requests": 100,
    "completed_requests": 98,
    "failed_requests": 2
  }
}

Webhook署名

Webhook設定でsecretを指定した場合、ペイロードはHMAC-SHA256で署名されます。 X-Codeer-SignatureX-Codeer-Timestampヘッダーを読み取り、{timestamp}.{raw_payload}で署名を検証してください:

import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
    signed_payload = f"{timestamp}.".encode("utf-8") + payload
    expected = hmac.new(
        secret.encode("utf-8"),
        signed_payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Webhookイベント

イベント 説明
batch.completed バッチ内のすべてのリクエストが処理されました
batch.failed バッチ処理が失敗しました
batch.cancelled バッチがキャンセルされました

コード例

Python

import requests
import time

API_KEY = "your-api-key"
BASE_URL = "https://api.codeer.ai/api/v1"

headers = {
    "x-api-key": API_KEY,
    "Content-Type": "application/json"
}

# バッチを作成
batch_response = requests.post(
    f"{BASE_URL}/batches",
    headers=headers,
    json={
        "agent_id": "your-agent-id",
        "requests": [
            {"custom_id": f"req-{i}", "message": f"質問 {i}"}
            for i in range(10)
        ]
    }
)
batch = batch_response.json()["data"]
batch_id = batch["id"]
print(f"バッチを作成しました:{batch_id}")

# 完了をポーリング
while True:
    status_response = requests.get(
        f"{BASE_URL}/batches/{batch_id}",
        headers=headers
    )
    status = status_response.json()["data"]["status"]
    print(f"バッチステータス:{status}")

    if status in ["completed", "failed", "cancelled"]:
        break
    time.sleep(5)

# 結果を取得
results_response = requests.get(
    f"{BASE_URL}/batches/{batch_id}/results",
    headers=headers
)
results = results_response.json()["data"]
for result in results:
    print(f"{result['custom_id']}: {result['status']}")
    if result["response_content"]:
        print(f"  応答:{result['response_content'][:100]}...")

JavaScript

const API_KEY = 'your-api-key';
const BASE_URL = 'https://api.codeer.ai/api/v1';

const headers = {
  'x-api-key': API_KEY,
  'Content-Type': 'application/json'
};

// バッチを作成
const batchResponse = await fetch(`${BASE_URL}/batches`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    agent_id: 'your-agent-id',
    requests: Array.from({ length: 10 }, (_, i) => ({
      custom_id: `req-${i}`,
      message: `質問 ${i}`
    }))
  })
});
const { data: batch } = await batchResponse.json();
console.log(`バッチを作成しました:${batch.id}`);

// 完了をポーリング
const pollBatch = async (batchId) => {
  while (true) {
    const statusResponse = await fetch(`${BASE_URL}/batches/${batchId}`, { headers });
    const { data } = await statusResponse.json();
    console.log(`バッチステータス:${data.status}`);

    if (['completed', 'failed', 'cancelled'].includes(data.status)) {
      return data;
    }
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
};

await pollBatch(batch.id);

// 結果を取得
const resultsResponse = await fetch(`${BASE_URL}/batches/${batch.id}/results`, { headers });
const { data: results } = await resultsResponse.json();
results.forEach(result => {
  console.log(`${result.custom_id}: ${result.status}`);
  if (result.response_content) {
    console.log(`  応答:${result.response_content.slice(0, 100)}...`);
  }
});