---
title: セッションイベントストリーム
url: https://platform.claude.com/docs/ja/managed-agents/events-and-streaming
description: イベントを送信し、レスポンスをストリーミングし、実行中のセッションを中断またはリダイレクトします。
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

Claude Managed Agentsとの通信はイベントベースです。ストリームを開いてセッションを追跡し、イベントを送信してセッションを指示し、セッションが入力待ちで一時停止したときに応答します。

## イベントタイプ

イベントは2つの方向に流れます。あなたがエージェントにイベントを送信し、セッションがあなたにイベントを送り返します。

* **送信するイベント：** `user.*` イベントはセッションを開始し、進行に合わせてセッションを誘導します。[`system.message`](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#send-system-messages) イベントはシステムレベルのコンテキストを追加します。
* **受信するイベント：** セッションイベント、スパンイベント、エージェントイベントは、セッションの状態とエージェントの進捗を報告します。

これらのイベントタイプ文字列は `{domain}.{action}` という命名規則に従います。完全な一覧については、リファレンスの[イベントタイプ](https://platform.claude.com/docs/ja/managed-agents/reference#event-types)を参照してください。

[Webhookイベントタイプ](https://platform.claude.com/docs/ja/managed-agents/webhooks#supported-event-types)は別物であり、一部の名前はストリームのものと異なります。たとえば、Webhookでは `session.status_idle` ではなく `session.status_idled` を使用します。

## イベントをストリーミングする

セッションからイベントをストリーミングして、エージェントの作業中にリアルタイムの更新を受け取ります。ストリームは開かれた後に発行されたイベントのみを配信するため、「race condition」（競合状態）を避けるために、イベントを送信する前にストリームを開いてください。

<CodeGroup>
  ```bash cURL
  # 最初のイベントを送信する前にストリームを開いてください。以降のイベントのみが配信されます。
  curl --fail-with-body -sS -N \
    "https://api.anthropic.com/v1/sessions/$SESSION_ID/events/stream?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "accept: text/event-stream"
  ```

  ```bash CLI
  # 最初のイベントを送信する前にストリームを開いてください。以降のイベントのみが配信されます。
  ant beta:sessions:events stream --session-id "$SESSION_ID"
  ```

  ```python Python
  # 先にストリームを開いてから、ユーザーメッセージを送信します
  with client.beta.sessions.events.stream(session.id) as stream:
      client.beta.sessions.events.send(
          session.id,
          events=[
              {
                  "type": "user.message",
                  "content": [{"type": "text", "text": "Summarize the repo README"}],
              },
          ],
      )

      for event in stream:
          match event.type:
              case "agent.message":
                  for block in event.content:
                      if block.type == "text":
                          print(block.text, end="")
              case "session.status_idle":
                  break
              case "session.error":
                  error_message = event.error.message if event.error else "unknown"
                  print(f"\n[Error: {error_message}]")
                  break
  ```

  ```typescript TypeScript
  // 先にストリームを開き、その後ユーザーメッセージを送信します
  const stream = await client.beta.sessions.events.stream(session.id);
  await client.beta.sessions.events.send(session.id, {
    events: [
      {
        type: "user.message",
        content: [{ type: "text", text: "Summarize the repo README" }]
      }
    ]
  });

  events: for await (const event of stream) {
    switch (event.type) {
      case "agent.message":
        for (const block of event.content) {
          if (block.type === "text") {
            process.stdout.write(block.text);
          }
        }
        break;
      case "session.status_idle":
        break events;
      case "session.error":
        console.log(`\n[Error: ${event.error?.message ?? "unknown"}]`);
        break events;
    }
  }
  ```

  ```csharp C#
  // 先にストリームを開いてから、ユーザーメッセージを送信します
  using var stream = await client.Beta.Sessions.Events.WithRawResponse.StreamStreaming(session.ID);
  await client.Beta.Sessions.Events.Send(session.ID, new()
  {
      Events =
      [
          new BetaManagedAgentsUserMessageEventParams
          {
              Type = BetaManagedAgentsUserMessageEventParamsType.UserMessage,
              Content =
              [
                  new BetaManagedAgentsTextBlock
                  {
                      Type = BetaManagedAgentsTextBlockType.Text,
                      Text = "Summarize the repo README",
                  },
              ],
          },
      ],
  });

  await foreach (var streamEvent in stream.Enumerate())
  {
      if (streamEvent.Value is BetaManagedAgentsAgentMessageEvent message)
      {
          foreach (var block in message.Content)
          {
              if (block.Value is BetaManagedAgentsTextBlock textBlock)
              {
                  Console.Write(textBlock.Text);
              }
          }
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionStatusIdleEvent)
      {
          break;
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionErrorEvent error)
      {
          Console.WriteLine($"\n[Error: {error.Error?.Message ?? "unknown"}]");
          break;
      }
  }
  ```

  ```go Go
  	// まずストリームを開き、その後ユーザーメッセージを送信します
  	stream := client.Beta.Sessions.Events.StreamEvents(ctx, session.ID, anthropic.BetaSessionEventStreamParams{})
  	defer stream.Close()

  	if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  		Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  				Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
  				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  					OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  						Type: anthropic.BetaManagedAgentsTextBlockTypeText,
  						Text: "Summarize the repo README",
  					},
  				}},
  			},
  		}},
  	}); err != nil {
  		panic(err)
  	}

  events:
  	for stream.Next() {
  		switch event := stream.Current().AsAny().(type) {
  		case anthropic.BetaManagedAgentsAgentMessageEvent:
  			// 具象型のリスト: BetaManagedAgentsTextBlock
  			for _, block := range event.Content {
  				fmt.Print(block.Text)
  			}
  		case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
  			break events
  		case anthropic.BetaManagedAgentsSessionErrorEvent:
  			fmt.Printf("\n[Error: %s]\n", cmp.Or(event.Error.Message, "unknown"))
  			break events
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  ```

  ```java Java
  // 先にストリームを開き、その後ユーザーメッセージを送信します
  try (var stream = client.beta().sessions().events().streamStreaming(session.id())) {
      client.beta().sessions().events().send(
          session.id(),
          EventSendParams.builder()
              .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
                  .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
                  .addTextContent("Summarize the repo README")
                  .build())
              .build()
      );

      Iterable<BetaManagedAgentsStreamSessionEvents> events = stream.stream()::iterator;
      events:
      for (var event : events) {
          switch (event.type().value()) {
              case AGENT_MESSAGE -> event.asAgentMessage().content().forEach(block -> block.text().ifPresent(textBlock -> IO.print(textBlock.text())));
              case SESSION_STATUS_IDLE -> {
                  break events;
              }
              case SESSION_ERROR -> {
                  // `message` フィールドはすべてのエラーバリアントに共通です。生の JSON から読み取ります。
                  var errorMessage =
                      event.asSessionError().error()._json().orElse(null) instanceof JsonObject json
                          ? json.values().get("message").asStringOrThrow()
                          : "unknown";
                  IO.println("\n[Error: " + errorMessage + "]");
                  break events;
              }
          }
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\Sessions\Events\ManagedAgentsAgentMessageEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionErrorEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock;

  // まずストリームを開き、その後ユーザーメッセージを送信します
  $stream = $client->beta->sessions->events->streamStream($session->id);
  $client->beta->sessions->events->send(
      $session->id,
      events: [
          [
              'type' => 'user.message',
              'content' => [['type' => 'text', 'text' => 'Summarize the repo README']],
          ],
      ],
  );

  foreach ($stream as $event) {
      match (true) {
          $event instanceof ManagedAgentsAgentMessageEvent => array_walk(
              $event->content,
              static fn ($block) => $block instanceof ManagedAgentsTextBlock ? print($block->text) : null,
          ),
          $event instanceof ManagedAgentsSessionErrorEvent => printf("\n[Error: %s]", $event->error?->message ?? 'unknown'),
          default => null,
      };
      if ($event->type === 'session.status_idle' || $event->type === 'session.error') {
          break;
      }
  }
  $stream->close();
  ```

  ```ruby Ruby
  # 先にストリームを開いてから、ユーザーメッセージを送信します
  stream = client.beta.sessions.events.stream_events(session.id)

  client.beta.sessions.events.send_(
    session.id,
    events: [{
      type: "user.message",
      content: [{type: "text", text: "Summarize the repo README"}]
    }]
  )

  stream.each do |event|
    case event
    when Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent
      event.content.each { print it.text }
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
      break
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionErrorEvent
      puts "\n[Error: #{event.error&.message || "unknown"}]"
      break
    else
      # その他のイベントタイプは無視します
    end
  end
  ```
</CodeGroup>

セッションは `session.error` イベントを通じてエラーを報告します。そのフィールドについては[イベントタイプ](https://platform.claude.com/docs/ja/managed-agents/reference#event-types)を参照してください。

エージェントのレスポンステキストはバッファリングされた `agent.message` イベントとして届き、各イベントはそれを生成したモデルリクエストが完了した後にのみ発行されます。モデルがまだ生成している間にテキストをレンダリングするには、[イベントデルタでレスポンスをプレビューする](https://platform.claude.com/docs/ja/managed-agents/event-deltas)を参照してください。

### イベントを見逃さずに再接続する

イベントを見逃さずに既存のセッションに再接続するには、新しいストリームとイベント履歴を組み合わせます。

1. 新しいストリームを開きます。
2. [完全なイベント履歴を一覧表示](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#list-past-events)して、確認済みイベントIDのセットを初期化します。
3. ライブストリームを追跡し、履歴一覧ですでに返されたイベントはスキップします。

<CodeGroup exclude="shell:cURL, shell:CLI">
  <CodeGroupItem language="cURL">
    このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するには[Claude SDK](https://platform.claude.com/docs/ja/cli-sdks-libraries/overview)を使用してください。
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するには[Claude SDK](https://platform.claude.com/docs/ja/cli-sdks-libraries/overview)を使用してください。
  </CodeGroupItem>

  ```python Python
  with client.beta.sessions.events.stream(session.id) as stream:
      # ストリームは開いてバッファリング中です。ライブ追跡の前に履歴を一覧取得します。
      history = client.beta.sessions.events.list(session.id)
      seen_event_ids = {past_event.id for past_event in history}

      # ライブイベントを追跡し、既に確認済みのものはスキップします
      for event in stream:
          if event.type == "event_start" or event.type == "event_delta":
              # この接続ではデルタプレビューが有効になっていません。
              continue
          if event.id in seen_event_ids:
              continue
          seen_event_ids.add(event.id)
          match event.type:
              case "agent.message":
                  for block in event.content:
                      if block.type == "text":
                          print(block.text, end="")
              case "session.status_idle":
                  break
  ```

  ```typescript TypeScript
  const seenEventIds = new Set<string>();
  const stream = await client.beta.sessions.events.stream(session.id);

  // ストリームは開いてバッファリング中です。ライブを追跡する前に履歴を一覧表示します。
  for await (const event of client.beta.sessions.events.list(session.id)) {
    seenEventIds.add(event.id);
  }

  // ライブイベントを追跡し、既に確認済みのものはスキップします
  tail: for await (const event of stream) {
    // プレビューイベント（event_start/event_delta）にはトップレベルの id がありません
    if (event.type === "event_start" || event.type === "event_delta") {
      continue;
    }
    if (seenEventIds.has(event.id)) {
      continue;
    }
    seenEventIds.add(event.id);
    switch (event.type) {
      case "agent.message":
        for (const block of event.content) {
          if (block.type === "text") {
            process.stdout.write(block.text);
          }
        }
        break;
      case "session.status_idle":
        break tail;
    }
  }
  ```

  ```csharp C#
  using var stream = await client.Beta.Sessions.Events.WithRawResponse.StreamStreaming(session.ID);

  // ストリームは開いてバッファリング中です。ライブ追跡の前に履歴を一覧表示します。
  HashSet<string> seenEventIds = [];
  var history = await client.Beta.Sessions.Events.List(session.ID);
  await foreach (var pastEvent in history.Paginate())
  {
      seenEventIds.Add(pastEvent.ID);
  }

  // 既に確認済みのものをスキップしながらライブイベントを追跡します
  await foreach (var streamEvent in stream.Enumerate())
  {
      if (!seenEventIds.Add(streamEvent.ID))
      {
          continue;
      }
      if (streamEvent.Value is BetaManagedAgentsAgentMessageEvent message)
      {
          foreach (var block in message.Content)
          {
              if (block.Value is BetaManagedAgentsTextBlock textBlock)
              {
                  Console.Write(textBlock.Text);
              }
          }
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionStatusIdleEvent)
      {
          break;
      }
  }
  ```

  ```go Go
  	stream := client.Beta.Sessions.Events.StreamEvents(ctx, session.ID, anthropic.BetaSessionEventStreamParams{})
  	defer stream.Close()

  	// ストリームは開いてバッファリング中です。ライブ追跡の前に履歴を一覧取得します。
  	seenEventIDs := map[string]struct{}{}
  	history := client.Beta.Sessions.Events.ListAutoPaging(ctx, session.ID, anthropic.BetaSessionEventListParams{})
  	for history.Next() {
  		seenEventIDs[history.Current().ID] = struct{}{}
  	}
  	if err := history.Err(); err != nil {
  		panic(err)
  	}

  	// 既に確認済みのものをスキップしつつ、ライブイベントを追跡します
  tail:
  	for stream.Next() {
  		event := stream.Current()
  		if _, seen := seenEventIDs[event.ID]; seen {
  			continue
  		}
  		seenEventIDs[event.ID] = struct{}{}
  		switch event := event.AsAny().(type) {
  		case anthropic.BetaManagedAgentsAgentMessageEvent:
  			// 具象型のリスト: BetaManagedAgentsTextBlock
  			for _, block := range event.Content {
  				fmt.Print(block.Text)
  			}
  		case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
  			break tail
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  ```

  ```java Java
  try (var stream = client.beta().sessions().events().streamStreaming(session.id())) {
      // ストリームは開いてバッファリング中です。ライブ追跡の前に履歴を一覧取得します。
      // すべてのイベントバリアントは `id` を持ちます。バリアント間で重複排除するため生の JSON から読み取ります。
      var seenEventIds = new HashSet<String>();
      for (var pastEvent : client.beta().sessions().events().list(session.id()).autoPager()) {
          if (pastEvent._json().orElseThrow() instanceof JsonObject json) {
              seenEventIds.add(json.values().get("id").asStringOrThrow());
          }
      }

      // ライブイベントを追跡します。既出の ID では Set.add が false を返すため、リプレイをスキップします。
      stream.stream()
          .filter(event -> event._json().orElseThrow() instanceof JsonObject json
              && seenEventIds.add(json.values().get("id").asStringOrThrow()))
          .takeWhile(event -> !event.isSessionStatusIdle())
          .filter(BetaManagedAgentsStreamSessionEvents::isAgentMessage)
          .forEach(event -> event.asAgentMessage().content()
              .forEach(block -> block.text().ifPresent(textBlock -> IO.print(textBlock.text()))));
  }
  ```

  ```php PHP
  use Anthropic\Beta\Sessions\Events\ManagedAgentsAgentMessageEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock;

  $stream = $client->beta->sessions->events->streamStream($session->id);

  // ストリームは開いてバッファリング中です。ライブ追跡の前に履歴を一覧取得します。
  $seenEventIds = [];
  foreach ($client->beta->sessions->events->list($session->id)->pagingEachItem() as $event) {
      $seenEventIds[$event->id] = true;
  }

  // ライブイベントを追跡し、既に確認済みのものはスキップします
  foreach ($stream as $event) {
      if (isset($seenEventIds[$event->id])) {
          continue;
      }
      $seenEventIds[$event->id] = true;
      match (true) {
          $event instanceof ManagedAgentsAgentMessageEvent => array_walk(
              $event->content,
              static fn ($block) => $block instanceof ManagedAgentsTextBlock ? print($block->text) : null,
          ),
          default => null,
      };
      if ($event->type === 'session.status_idle') {
          break;
      }
  }
  $stream->close();
  ```

  ```ruby Ruby
  stream = client.beta.sessions.events.stream_events(session.id)

  # ストリームは開いてバッファリング中です。ライブ追跡の前に履歴を一覧取得します。
  seen_event_ids = Set.new
  client.beta.sessions.events.list(session.id).auto_paging_each { seen_event_ids << it.id }

  # 既に見たものをスキップしつつライブイベントを追跡します — Set#add? は重複時に nil を返します
  stream.each do |event|
    next unless seen_event_ids.add?(event.id)
    case event
    when Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent
      event.content.each { print it.text }
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
      break
    else
      # その他のイベントタイプは無視します
    end
  end
  ```
</CodeGroup>

## イベントを送信する

`user.message` イベントを送信して、エージェントの作業を開始または継続します。

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d '{
      "events": [
        {
          "type": "user.message",
          "content": [
            {"type": "text", "text": "Analyze the performance of the sort function in utils.py"}
          ]
        }
      ]
    }'
  ```

  ```bash CLI
  ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
  events:
    - type: user.message
      content:
        - type: text
          text: Analyze the performance of the sort function in utils.py
  YAML
  ```

  ```python Python
  client.beta.sessions.events.send(
      session.id,
      events=[
          {
              "type": "user.message",
              "content": [
                  {
                      "type": "text",
                      "text": "Analyze the performance of the sort function in utils.py",
                  },
              ],
          },
      ],
  )
  ```

  ```typescript TypeScript
  await client.beta.sessions.events.send(session.id, {
    events: [
      {
        type: "user.message",
        content: [
          {
            type: "text",
            text: "Analyze the performance of the sort function in utils.py"
          }
        ]
      }
    ]
  });
  ```

  ```csharp C#
  await client.Beta.Sessions.Events.Send(session.ID, new()
  {
      Events =
      [
          new BetaManagedAgentsUserMessageEventParams
          {
              Type = BetaManagedAgentsUserMessageEventParamsType.UserMessage,
              Content =
              [
                  new BetaManagedAgentsTextBlock
                  {
                      Type = BetaManagedAgentsTextBlockType.Text,
                      Text = "Analyze the performance of the sort function in utils.py",
                  },
              ],
          },
      ],
  });
  ```

  ```go Go
  if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  	Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  		OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  			Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
  			Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  				OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  					Type: anthropic.BetaManagedAgentsTextBlockTypeText,
  					Text: "Analyze the performance of the sort function in utils.py",
  				},
  			}},
  		},
  	}},
  }); err != nil {
  	panic(err)
  }
  ```

  ```java Java
  client.beta().sessions().events().send(
      session.id(),
      EventSendParams.builder()
          .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
              .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
              .addTextContent("Analyze the performance of the sort function in utils.py")
              .build())
          .build());
  ```

  ```php PHP
  $client->beta->sessions->events->send(
      $session->id,
      events: [
          [
              'type' => 'user.message',
              'content' => [
                  [
                      'type' => 'text',
                      'text' => 'Analyze the performance of the sort function in utils.py',
                  ],
              ],
          ],
      ],
  );
  ```

  ```ruby Ruby
  client.beta.sessions.events.send_(
    session.id,
    events: [
      {
        type: "user.message",
        content: [
          {
            type: "text",
            text: "Analyze the performance of the sort function in utils.py"
          }
        ]
      }
    ]
  )
  ```
</CodeGroup>

セッション履歴内のすべてのイベントには `processed_at` (java, php: `processedAt`; csharp, go: `ProcessedAt`) タイムスタンプが含まれ、イベントの処理が完了した時点で設定されます。送信したイベントでは、イベントがまだ先行するイベントの後ろでキューに入っている間、`processed_at` (java, php: `processedAt`; csharp, go: `ProcessedAt`) は `null` (python: `None`; ruby: `nil`; java: `Optional.empty()`; go: `time.Time{}`) です。例外は `user.define_outcome`、`user.custom_tool_result`、`user.tool_result` で、これらは受信時に処理され、`processed_at` (java, php: `processedAt`; csharp, go: `ProcessedAt`) がすでに設定された状態でエコーバックされます。

## セッションがアイドルになったときに応答する

`session.status_idle` イベントは、エージェントが停止して入力を待っていることを意味します。その `stop_reason.type` が理由を示します。

| `stop_reason.type` | セッションが停止した理由                                                                                                                | 対処方法                                                                                                                                        |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `end_turn`         | エージェントがターンを終了したか、[あなたが中断しました](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#interrupt-the-agent)。 | エージェントに追加の作業がある場合は[`user.message` を送信します](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#resume-an-idle-session)。  |
| `requires_action`  | カスタムツール呼び出しや確認リクエストなど、1つ以上のツール呼び出しにあなたからの応答が必要です。                                                                           | [ブロックしている各ツール呼び出しに応答します](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#answer-tool-calls-that-pause-the-session)。 |
| `budget_reached`   | セッションの追跡された定価コストが[予算](https://platform.claude.com/docs/ja/managed-agents/budgets)に達しました。                                    | [予算を変更または削除します](https://platform.claude.com/docs/ja/managed-agents/budgets#resume-a-session-at-its-budget)。                                 |

予算で一時停止したセッションを、送信するイベントで再開することはできません。予算によって一時停止された作業は、予算を消費済みの定価コストを上回る値に変更するか、予算を削除すると自動的に再開されます。作業が再開されると、セッションは[予算によって一時停止されたワークフロー実行](https://platform.claude.com/docs/ja/managed-agents/workflow-runs#budgets-and-limits)ごとに `workflow_run.status_running` イベントを発行します。中断によって一時停止された実行は一時停止したままです。[予算に達したセッションを再開する](https://platform.claude.com/docs/ja/managed-agents/budgets#resume-a-session-at-its-budget)を参照してください。一時停止を示すイベントと、セッションが引き続き受け付けるイベントについては、[セッションが予算に達したとき](https://platform.claude.com/docs/ja/managed-agents/budgets#when-a-session-reaches-its-budget)を参照してください。

## セッションを一時停止させるツール呼び出しに応答する

セッションは、エージェントが[カスタムツール](https://platform.claude.com/docs/ja/managed-agents/tools#custom-tools)を呼び出したとき、および[権限ポリシー](https://platform.claude.com/docs/ja/managed-agents/permission-policies)のもとでツール呼び出しにあなたの確認が必要なときに一時停止します。どちらの一時停止も同じ手順に従います。

1. セッションはツール呼び出しを `agent.custom_tool_use`、`agent.tool_use`、または `agent.mcp_tool_use` イベントとして発行します。
2. セッションは、`stop_reason.type` が `requires_action` である `session.status_idle` イベントとともに一時停止します。ブロックしているイベントIDは `stop_reason.event_ids` 配列に含まれます。
3. ブロックしている各イベントIDについて、[`user.custom_tool_result`](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#return-a-custom-tool-result) または [`user.tool_confirmation`](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#confirm-a-tool-call) イベントを送信します。カスタムツールの結果は手順2を待つ必要はありません。
4. ブロックしているすべてのイベントが解決されると、セッションは `running` に戻ります。

マルチエージェントセッションでは、サブエージェントのブロックしているイベントはプライマリスレッドにもクロスポストされます。[ツール権限とカスタムツール](https://platform.claude.com/docs/ja/managed-agents/session-threads#tool-permissions-and-custom-tools)を参照してください。

### カスタムツールの結果を返す

`agent.custom_tool_use` イベントにはツール名と入力が含まれます。あなたのシステムでツールを実行します。次に、`user.custom_tool_result` イベントを送信し、`custom_tool_use_id` (java: `customToolUseId`; php: `customToolUseID`; csharp, go: `CustomToolUseID`) パラメータにイベントIDを、結果のコンテンツとともに渡します。

`session.status_idle` を待たずに、`agent.custom_tool_use` イベントが届いた時点ですぐに結果を送信できます。セッションはその呼び出しに対して `requires_action` の停止理由を持つ `session.status_idle` を引き続き発行しますが、クライアントはそれを無視できます。同じ呼び出しに対する2回目の結果は受け付けられますが、効果はありません。

一時停止したセッションに[再接続](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#reconnect-without-missing-events)した場合、最新の `session.status_idle` イベントの `stop_reason.event_ids` に応答すべき呼び出しが一覧表示されます。

次の例では、各呼び出しが届くたびに応答します。

<CodeGroup exclude="shell:cURL, shell:CLI">
  <CodeGroupItem language="cURL">
    このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するには[Claude SDK](https://platform.claude.com/docs/ja/cli-sdks-libraries/overview)を使用してください。
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するには[Claude SDK](https://platform.claude.com/docs/ja/cli-sdks-libraries/overview)を使用してください。
  </CodeGroupItem>

  ```python Python
  with client.beta.sessions.events.stream(session.id) as stream:
      for event in stream:
          match event.type:
              case "agent.custom_tool_use":
                  # ツールを実行します
                  result = call_tool(event.name, event.input)

                  # 結果を送り返します
                  client.beta.sessions.events.send(
                      session.id,
                      events=[
                          {
                              "type": "user.custom_tool_result",
                              "custom_tool_use_id": event.id,
                              "content": [{"type": "text", "text": result}],
                          },
                      ],
                  )
              case "session.status_idle":
                  if event.stop_reason and event.stop_reason.type == "end_turn":
                      break
  ```

  ```typescript TypeScript
  const stream = await client.beta.sessions.events.stream(session.id);

  loop: for await (const event of stream) {
    switch (event.type) {
      case "agent.custom_tool_use": {
        // ツールを実行します
        const result = await callTool(event.name, event.input);

        // 結果を送り返します
        await client.beta.sessions.events.send(session.id, {
          events: [
            {
              type: "user.custom_tool_result",
              custom_tool_use_id: event.id,
              content: [{ type: "text", text: result }]
            }
          ]
        });
        break;
      }
      case "session.status_idle":
        if (event.stop_reason.type === "end_turn") {
          break loop;
        }
        break;
    }
  }
  ```

  ```csharp C#
  await foreach (var streamEvent in client.Beta.Sessions.Events.StreamStreaming(session.ID))
  {
      if (streamEvent.Value is BetaManagedAgentsAgentCustomToolUseEvent toolUse)
      {
          // ツールを実行します
          var result = await CallTool(toolUse.Name, toolUse.Input);

          // 結果を送り返します
          await client.Beta.Sessions.Events.Send(session.ID, new()
          {
              Events =
              [
                  new BetaManagedAgentsUserCustomToolResultEventParams
                  {
                      Type = BetaManagedAgentsUserCustomToolResultEventParamsType.UserCustomToolResult,
                      CustomToolUseID = toolUse.ID,
                      Content =
                      [
                          new BetaManagedAgentsTextBlock
                          {
                              Type = BetaManagedAgentsTextBlockType.Text,
                              Text = result,
                          },
                      ],
                  },
              ],
          });
      }
      else if (streamEvent.Value is BetaManagedAgentsSessionStatusIdleEvent idle
          && idle.StopReason?.Value is BetaManagedAgentsSessionEndTurn)
      {
          break;
      }
  }
  ```

  ```go Go
  	stream := client.Beta.Sessions.Events.StreamEvents(ctx, session.ID, anthropic.BetaSessionEventStreamParams{})
  	defer stream.Close()

  loop:
  	for stream.Next() {
  		switch event := stream.Current().AsAny().(type) {
  		case anthropic.BetaManagedAgentsAgentCustomToolUseEvent:
  			// ツールを実行します
  			result := callTool(event.Name, event.Input)
  			// 結果を送り返します
  			if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  				Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  					OfUserCustomToolResult: &anthropic.BetaManagedAgentsUserCustomToolResultEventParams{
  						Type:            anthropic.BetaManagedAgentsUserCustomToolResultEventParamsTypeUserCustomToolResult,
  						CustomToolUseID: event.ID,
  						Content: []anthropic.BetaManagedAgentsUserCustomToolResultEventParamsContentUnion{{
  							OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  								Type: anthropic.BetaManagedAgentsTextBlockTypeText,
  								Text: result,
  							},
  						}},
  					},
  				}},
  			}); err != nil {
  				panic(err)
  			}
  		case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
  			if _, ok := event.StopReason.AsAny().(anthropic.BetaManagedAgentsSessionEndTurn); ok {
  				break loop
  			}
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  ```

  ```java Java
  try (var stream = client.beta().sessions().events().streamStreaming(session.id())) {
      loop:
      for (var event : (Iterable<BetaManagedAgentsStreamSessionEvents>) stream.stream()::iterator) {
          switch (event.type().value()) {
              case AGENT_CUSTOM_TOOL_USE -> {
                  // ツールを実行します
                  var toolUse = event.asAgentCustomToolUse();
                  var result = callTool(toolUse.name(), toolUse.input());

                  // 結果を送り返します
                  client.beta().sessions().events().send(
                      session.id(),
                      EventSendParams.builder()
                          .addEvent(BetaManagedAgentsUserCustomToolResultEventParams.builder()
                              .type(BetaManagedAgentsUserCustomToolResultEventParams.Type.USER_CUSTOM_TOOL_RESULT)
                              .customToolUseId(toolUse.id())
                              .addTextContent(result)
                              .build())
                          .build());
              }
              case SESSION_STATUS_IDLE -> {
                  if (event.asSessionStatusIdle().stopReason().isEndTurn()) {
                      break loop;
                  }
              }
          }
      }
  }
  ```

  ```php PHP
  $stream = $client->beta->sessions->events->streamStream($session->id);

  foreach ($stream as $event) {
      switch (true) {
          case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsAgentCustomToolUseEvent:
              // ツールを実行します
              $result = callTool($event->name, $event->input);

              // 結果を送り返します
              $client->beta->sessions->events->send(
                  $session->id,
                  events: [
                      [
                          'type' => 'user.custom_tool_result',
                          'custom_tool_use_id' => $event->id,
                          'content' => [['type' => 'text', 'text' => $result]],
                      ],
                  ],
              );
              break;
          case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusIdleEvent:
              if ($event->stopReason instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionEndTurn) {
                  break 2;
              }
              break;
      }
  }
  ```

  ```ruby Ruby
  client.beta.sessions.events.stream_events(session.id).each do |event|
    case event
    when Anthropic::Beta::Sessions::BetaManagedAgentsAgentCustomToolUseEvent
      # ツールを実行します
      result = call_tool.call(event.name, event.input)
      # 結果を送り返します
      client.beta.sessions.events.send_(
        session.id,
        events: [
          {
            type: "user.custom_tool_result",
            custom_tool_use_id: event.id,
            content: [{type: "text", text: result}]
          }
        ]
      )
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
      break if event.stop_reason.is_a?(Anthropic::Beta::Sessions::BetaManagedAgentsSessionEndTurn)
    end
  end
  ```
</CodeGroup>

エージェントに開いている[ワークフロー実行](https://platform.claude.com/docs/ja/managed-agents/workflow-runs)がある場合、セッションが `running` のままでもカスタムツール呼び出しが届くことがあります。`requires_action` のアイドルイベントは、[セッションのスレッド](https://platform.claude.com/docs/ja/managed-agents/session-threads)がどれも作業していないときにのみ届きます。それを待たずに、各呼び出しの `agent.custom_tool_use` イベントが届いたときに応答してください。その方法は[実行を追跡する](https://platform.claude.com/docs/ja/managed-agents/workflow-runs#follow-a-run)のサンプルで示されています。

### ツール呼び出しを確認する

`user.tool_confirmation` イベントを送信し、`tool_use_id` (java: `toolUseId`; php: `toolUseID`; csharp, go: `ToolUseID`) パラメータにイベントIDを渡します。`result` (csharp, go: `Result`) を `"allow"` または `"deny"` に設定します。どの呼び出しが確認を待つか、および拒否の理由を説明する方法については、[確認リクエストに応答する](https://platform.claude.com/docs/ja/managed-agents/permission-policies#respond-to-confirmation-requests)を参照してください。

次の例では、保留中のすべての呼び出しを承認します。

<CodeGroup exclude="shell:cURL, shell:CLI">
  <CodeGroupItem language="cURL">
    このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するには[Claude SDK](https://platform.claude.com/docs/ja/cli-sdks-libraries/overview)を使用してください。
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    このワークフローには、単一のシェルコマンドでは実現できないロジックが必要です。実行するには[Claude SDK](https://platform.claude.com/docs/ja/cli-sdks-libraries/overview)を使用してください。
  </CodeGroupItem>

  ```python Python
  with client.beta.sessions.events.stream(session.id) as stream:
      for event in stream:
          if event.type == "session.status_idle" and (stop_reason := event.stop_reason):
              match stop_reason.type:
                  case "requires_action":
                      for event_id in stop_reason.event_ids:
                          # 保留中のツール呼び出しを承認
                          client.beta.sessions.events.send(
                              session.id,
                              events=[
                                  {
                                      "type": "user.tool_confirmation",
                                      "tool_use_id": event_id,
                                      "result": "allow",
                                  },
                              ],
                          )
                  case "end_turn":
                      break
  ```

  ```typescript TypeScript
  const stream = await client.beta.sessions.events.stream(session.id);

  for await (const event of stream) {
    if (event.type !== "session.status_idle") {
      continue;
    }
    if (event.stop_reason.type === "end_turn") {
      break;
    }
    if (event.stop_reason.type !== "requires_action") {
      continue;
    }

    for (const eventId of event.stop_reason.event_ids) {
      // 保留中のツール呼び出しを承認
      await client.beta.sessions.events.send(session.id, {
        events: [
          {
            type: "user.tool_confirmation",
            tool_use_id: eventId,
            result: "allow"
          }
        ]
      });
    }
  }
  ```

  ```csharp C#
  await foreach (var streamEvent in client.Beta.Sessions.Events.StreamStreaming(session.ID))
  {
      if (streamEvent.Value is not BetaManagedAgentsSessionStatusIdleEvent idle) continue;

      if (idle.StopReason?.Value is BetaManagedAgentsSessionRequiresAction requiresAction)
      {
          foreach (var eventId in requiresAction.EventIds)
          {
              // 保留中のツール呼び出しを承認
              await client.Beta.Sessions.Events.Send(session.ID, new()
              {
                  Events =
                  [
                      new BetaManagedAgentsUserToolConfirmationEventParams
                      {
                          Type = BetaManagedAgentsUserToolConfirmationEventParamsType.UserToolConfirmation,
                          ToolUseID = eventId,
                          Result = BetaManagedAgentsUserToolConfirmationEventParamsResult.Allow,
                      },
                  ],
              });
          }
      }
      else if (idle.StopReason?.Value is BetaManagedAgentsSessionEndTurn)
      {
          break;
      }
  }
  ```

  ```go Go
  	stream := client.Beta.Sessions.Events.StreamEvents(ctx, session.ID, anthropic.BetaSessionEventStreamParams{})
  	defer stream.Close()

  loop:
  	for stream.Next() {
  		event, ok := stream.Current().AsAny().(anthropic.BetaManagedAgentsSessionStatusIdleEvent)
  		if !ok {
  			continue
  		}
  		switch stopReason := event.StopReason.AsAny().(type) {
  		case anthropic.BetaManagedAgentsSessionRequiresAction:
  			for _, eventID := range stopReason.EventIDs {
  				// 保留中のツール呼び出しを承認します
  				if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  					Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  						OfUserToolConfirmation: &anthropic.BetaManagedAgentsUserToolConfirmationEventParams{
  							Type:      anthropic.BetaManagedAgentsUserToolConfirmationEventParamsTypeUserToolConfirmation,
  							ToolUseID: eventID,
  							Result:    anthropic.BetaManagedAgentsUserToolConfirmationEventParamsResultAllow,
  						},
  					}},
  				}); err != nil {
  					panic(err)
  				}
  			}
  		case anthropic.BetaManagedAgentsSessionEndTurn:
  			break loop
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  ```

  ```java Java
  try (var stream = client.beta().sessions().events().streamStreaming(session.id())) {
      stream.stream()
          .filter(BetaManagedAgentsStreamSessionEvents::isSessionStatusIdle)
          .map(idleEvent -> idleEvent.asSessionStatusIdle().stopReason())
          .takeWhile(stopReason -> !stopReason.isEndTurn())
          .filter(stopReason -> stopReason.isRequiresAction())
          .flatMap(stopReason -> stopReason.asRequiresAction().eventIds().stream())
          // 保留中の各ツール呼び出しを承認します
          .forEach(toolUseId -> client.beta().sessions().events().send(
              session.id(),
              EventSendParams.builder()
                  .addEvent(BetaManagedAgentsUserToolConfirmationEventParams.builder()
                      .type(BetaManagedAgentsUserToolConfirmationEventParams.Type.USER_TOOL_CONFIRMATION)
                      .toolUseId(toolUseId)
                      .result(BetaManagedAgentsUserToolConfirmationEventParams.Result.ALLOW)
                      .build())
                  .build()));
  }
  ```

  ```php PHP
  $stream = $client->beta->sessions->events->streamStream($session->id);

  foreach ($stream as $event) {
      if ($event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusIdleEvent && $event->stopReason) {
          switch (true) {
              case $event->stopReason instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionRequiresAction:
                  foreach ($event->stopReason->eventIDs as $eventId) {
                      // 保留中のツール呼び出しを承認します
                      $client->beta->sessions->events->send(
                          $session->id,
                          events: [
                              [
                                  'type' => 'user.tool_confirmation',
                                  'tool_use_id' => $eventId,
                                  'result' => 'allow',
                              ],
                          ],
                      );
                  }
                  break;
              case $event->stopReason instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionEndTurn:
                  break 2;
          }
      }
  }
  ```

  ```ruby Ruby
  client.beta.sessions.events.stream_events(session.id).each do |event|
    case event
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
      stop_reason = event.stop_reason
      case stop_reason
      when Anthropic::Beta::Sessions::BetaManagedAgentsSessionRequiresAction
        stop_reason.event_ids.each do |event_id|
          # 保留中のツール呼び出しを承認します
          client.beta.sessions.events.send_(
            session.id,
            events: [
              {type: "user.tool_confirmation", tool_use_id: event_id, result: "allow"}
            ]
          )
        end
      when Anthropic::Beta::Sessions::BetaManagedAgentsSessionEndTurn
        break
      end
    end
  end
  ```
</CodeGroup>

前の例では、セッションがアイドルになった後に各呼び出しを承認します。エージェントに開いている[ワークフロー実行](https://platform.claude.com/docs/ja/managed-agents/workflow-runs)がある場合、セッションが `running` のままでもツール呼び出しがあなたの確認を待つことがあります。アイドルイベントを待たずに、[`evaluated_permission` (java, php: `evaluatedPermission`; csharp, go: `EvaluatedPermission`)](https://platform.claude.com/docs/ja/managed-agents/permission-policies#see-how-each-call-was-evaluated) が `ask` である `agent.tool_use` または `agent.mcp_tool_use` イベントが届いたときに応答してください。[実行を追跡する](https://platform.claude.com/docs/ja/managed-agents/workflow-runs#follow-a-run)のサンプルはこの方法でカスタムツール呼び出しに応答しており、その導入部で確認を追加する方法を説明しています。

## アイドル状態のセッションを再開する

セッションはインタラクション間で保持されます。セッションを再開するには、通常どおり `user.message` イベントを送信します。

<CodeGroup>
  ```bash cURL
  # 本番環境では、再開したいセッションの保存済み ID を渡します。
  curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d '{
      "events": [
        {
          "type": "user.message",
          "content": [
            {"type": "text", "text": "Now run the tests against the changes you made earlier."}
          ]
        }
      ]
    }'
  ```

  ```bash CLI
  # 本番環境では、再開したいセッションの保存済み ID を渡してください。
  ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
  events:
    - type: user.message
      content:
        - type: text
          text: Now run the tests against the changes you made earlier.
  YAML
  ```

  ```python Python
  # 新しい user.message イベントを送信して、以前に作成したセッションを再開します。
  # 本番環境では、再開したいセッションの保存済み ID を渡してください。
  client.beta.sessions.events.send(
      session.id,
      events=[
          {
              "type": "user.message",
              "content": [
                  {
                      "type": "text",
                      "text": "Now run the tests against the changes you made earlier.",
                  },
              ],
          },
      ],
  )
  ```

  ```typescript TypeScript
  // 以前作成したセッションに新しいユーザーイベントを送信して再開します。
  // 本番環境では、再開したいセッションの保存済み ID を渡してください。
  await client.beta.sessions.events.send(session.id, {
    events: [
      {
        type: "user.message",
        content: [
          {
            type: "text",
            text: "Now run the tests against the changes you made earlier."
          }
        ]
      }
    ]
  });
  ```

  ```csharp C#
  // 以前に作成したセッションを ID で再開します。本番環境では、
  // セッション作成時に保存したセッション ID を渡してください。
  await client.Beta.Sessions.Events.Send(session.ID, new()
  {
      Events =
      [
          new BetaManagedAgentsUserMessageEventParams
          {
              Type = BetaManagedAgentsUserMessageEventParamsType.UserMessage,
              Content =
              [
                  new BetaManagedAgentsTextBlock
                  {
                      Type = BetaManagedAgentsTextBlockType.Text,
                      Text = "Now run the tests against the changes you made earlier.",
                  },
              ],
          },
      ],
  });
  ```

  ```go Go
  // 新しい user.message イベントを送信して、以前に作成したセッションを再開します。
  // 本番環境では、再開するセッションの保存済み ID を渡してください。
  if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  	Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  		OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  			Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
  			Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  				OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  					Type: anthropic.BetaManagedAgentsTextBlockTypeText,
  					Text: "Now run the tests against the changes you made earlier.",
  				},
  			}},
  		},
  	}},
  }); err != nil {
  	panic(err)
  }
  ```

  ```java Java
  // 以前に作成したセッションを ID で再開します。本番環境では、
  // セッション作成時に保存したセッション ID を渡してください。
  client.beta().sessions().events().send(
      session.id(),
      EventSendParams.builder()
          .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
              .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
              .addTextContent("Now run the tests against the changes you made earlier.")
              .build())
          .build());
  ```

  ```php PHP
  // 新しい user.message イベントを送信して、以前に作成したセッションを再開します。
  // 本番環境では、セッション作成時に保存したセッション ID を渡してください。
  $client->beta->sessions->events->send(
      $session->id,
      events: [
          [
              'type' => 'user.message',
              'content' => [
                  [
                      'type' => 'text',
                      'text' => 'Now run the tests against the changes you made earlier.',
                  ],
              ],
          ],
      ],
  );
  ```

  ```ruby Ruby
  # セッションの再開は、次のイベントを送信するだけです。本番環境では、
  # セッション作成時に保存したセッション ID を渡してください。
  client.beta.sessions.events.send_(
    session.id,
    events: [
      {
        type: "user.message",
        content: [
          {type: "text", text: "Now run the tests against the changes you made earlier."}
        ]
      }
    ]
  )
  ```
</CodeGroup>

会話履歴は、セッションが明示的に削除されない限り保持されます。セッションがアイドルになると、そのサンドボックスはチェックポイントされます。チェックポイントは、ファイルシステム、インストール済みパッケージ、エージェントが作成したファイルを含む、サンドボックスの完全な状態を保持します。

<Note>
  サンドボックスの状態はサンドボックスの作成から30日間のみ保持され、アクティビティによってこの期間が延長されることはありません。30日を過ぎると、サンドボックスの状態（ファイル、インストール済みツールなど）は復元できなくなり、再開されたセッションは新しいサンドボックスから開始されます。ワークフローがサンドボックスの内容に依存している場合は、期間が終了する前に、エージェントに重要な成果物を[出力](https://platform.claude.com/docs/ja/managed-agents/define-outcomes#retrieving-deliverables)に書き込ませてください。
</Note>

## エージェントを中断する

`user.interrupt` イベントを送信して実行中のエージェントを停止し、続けて `user.message` イベントを送信してリダイレクトします。

<CodeGroup>
  ```bash cURL
  # エージェントは現在ファイルを分析中...
  # 新しい指示で中断:
  curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d '{
      "events": [
        {"type": "user.interrupt"},
        {
          "type": "user.message",
          "content": [
            {"type": "text", "text": "Instead, focus on fixing the bug in line 42."}
          ]
        }
      ]
    }'
  ```

  ```bash CLI
  # エージェントは現在ファイルを分析中...
  # 新しい指示で割り込みます:
  ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
  events:
    - type: user.interrupt
    - type: user.message
      content:
        - type: text
          text: Instead, focus on fixing the bug in line 42.
  YAML
  ```

  ```python Python
  # エージェントは現在ファイルを分析中...
  # 新しい指示で中断:
  client.beta.sessions.events.send(
      session.id,
      events=[
          {"type": "user.interrupt"},
          {
              "type": "user.message",
              "content": [
                  {
                      "type": "text",
                      "text": "Instead, focus on fixing the bug in line 42.",
                  },
              ],
          },
      ],
  )
  ```

  ```typescript TypeScript
  // エージェントは現在ファイルを分析中...
  // 新しい指示で中断：
  await client.beta.sessions.events.send(session.id, {
    events: [
      { type: "user.interrupt" },
      {
        type: "user.message",
        content: [
          {
            type: "text",
            text: "Instead, focus on fixing the bug in line 42."
          }
        ]
      }
    ]
  });
  ```

  ```csharp C#
  // エージェントは現在ファイルを分析中...
  // 新しい指示で中断：
  await client.Beta.Sessions.Events.Send(session.ID, new()
  {
      Events =
      [
          new BetaManagedAgentsUserInterruptEventParams
          {
              Type = BetaManagedAgentsUserInterruptEventParamsType.UserInterrupt,
          },
          new BetaManagedAgentsUserMessageEventParams
          {
              Type = BetaManagedAgentsUserMessageEventParamsType.UserMessage,
              Content =
              [
                  new BetaManagedAgentsTextBlock
                  {
                      Type = BetaManagedAgentsTextBlockType.Text,
                      Text = "Instead, focus on fixing the bug in line 42.",
                  },
              ],
          },
      ],
  });
  ```

  ```go Go
  // エージェントは現在ファイルを分析中です...
  // 新しい指示で中断します:
  if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  	Events: []anthropic.BetaManagedAgentsEventParamsUnion{
  		{
  			OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{
  				Type: anthropic.BetaManagedAgentsUserInterruptEventParamsTypeUserInterrupt,
  			},
  		},
  		{
  			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  				Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
  				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  					OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  						Type: anthropic.BetaManagedAgentsTextBlockTypeText,
  						Text: "Instead, focus on fixing the bug in line 42.",
  					},
  				}},
  			},
  		},
  	},
  }); err != nil {
  	panic(err)
  }
  ```

  ```java Java
  // エージェントは現在ファイルを分析中です...
  // 新しい指示で中断します：
  client.beta().sessions().events().send(
      session.id(),
      EventSendParams.builder()
          .addEvent(BetaManagedAgentsUserInterruptEventParams.builder()
              .type(BetaManagedAgentsUserInterruptEventParams.Type.USER_INTERRUPT)
              .build())
          .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
              .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
              .addTextContent("Instead, focus on fixing the bug in line 42.")
              .build())
          .build());
  ```

  ```php PHP
  // エージェントは現在ファイルを分析中です...
  // 新しい指示で中断します:
  $client->beta->sessions->events->send(
      $session->id,
      events: [
          ['type' => 'user.interrupt'],
          [
              'type' => 'user.message',
              'content' => [
                  [
                      'type' => 'text',
                      'text' => 'Instead, focus on fixing the bug in line 42.',
                  ],
              ],
          ],
      ],
  );
  ```

  ```ruby Ruby
  # エージェントは現在ファイルを分析中...
  # 新しい指示で中断：
  client.beta.sessions.events.send_(
    session.id,
    events: [
      {type: "user.interrupt"},
      {
        type: "user.message",
        content: [
          {type: "text", text: "Instead, focus on fixing the bug in line 42."}
        ]
      }
    ]
  )
  ```
</CodeGroup>

呼び出しはイベントがキューに入るとすぐに返ります。その後、中断は次の順序で有効になります。

1. エージェントが中断を適用します。それまでの間、中断の `processed_at` (java, php: `processedAt`; csharp, go: `ProcessedAt`) は `null` (python: `None`; ruby: `nil`; java: `Optional.empty()`; go: `time.Time{}`) のままで、セッションは `running` のままです。進行中のモデルレスポンスは即座に停止しますが、ツール呼び出しの実行中は中断の適用に時間がかかることがあります。
2. `user.interrupt` イベントがストリームに現れ、中断されたターンは `session.status_idle` イベントで終了します。
3. エージェントは、中断の後に送信した `user.message` で次のターンを開始します。

アイドルイベントの `stop_reason.type` は `end_turn` で、自然に終了したターンと同じ値です。ワークフロー実行が開いている場合、中断によってそれらが終了することはありません。実行中の実行があるとセッションが `running` のままになることがあるため、手順2の `session.status_idle` イベントが届かない場合があります。[実行が開いているセッションを中断する](https://platform.claude.com/docs/ja/managed-agents/workflow-runs#interrupt-a-session-with-runs-open)を参照してください。

## 過去のイベントを一覧表示する

セッションの完全なイベント履歴を取得します。

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json"
  ```

  ```bash CLI
  ant beta:sessions:events list --session-id "$SESSION_ID" --format jsonl
  ```

  ```python Python
  events = client.beta.sessions.events.list(session.id)
  for event in events.data:
      print(f"[{event.type}] {event.processed_at}")
  ```

  ```typescript TypeScript
  const events = await client.beta.sessions.events.list(session.id);
  for (const event of events.data) {
    console.log(`[${event.type}] ${event.processed_at}`);
  }
  ```

  ```csharp C#
  var events = await client.Beta.Sessions.Events.List(session.ID);
  foreach (var sessionEvent in events.Items)
  {
      Console.WriteLine($"[{sessionEvent.Json.GetProperty("type").GetString()}] {sessionEvent.ProcessedAt}");
  }
  ```

  ```go Go
  events, err := client.Beta.Sessions.Events.List(ctx, session.ID, anthropic.BetaSessionEventListParams{})
  if err != nil {
  	panic(err)
  }
  for _, event := range events.Data {
  	fmt.Printf("[%s] %s\n", event.Type, event.ProcessedAt)
  }
  ```

  ```java Java
  var events = client.beta().sessions().events().list(session.id());
  for (var event : events.data()) {
      var eventJson = event._json().orElseThrow().convert(JsonNode.class);
      var processedAt = eventJson.path("processed_at");
      IO.println("[" + eventJson.get("type").asText() + "] "
          + (processedAt.isTextual() ? processedAt.asText() : "null"));
  }
  ```

  ```php PHP
  $events = $client->beta->sessions->events->list($session->id);
  foreach ($events->data as $event) {
      $processedAt = ($event->processedAt ?? null)?->format(DATE_RFC3339) ?? 'null';
      echo "[{$event->type}] {$processedAt}\n";
  }
  ```

  ```ruby Ruby
  events = client.beta.sessions.events.list(session.id)
  events.data.each { puts "[#{it.type}] #{it.processed_at}" }
  ```
</CodeGroup>

特定のイベントタイプのみを返すには、`types` (curl: `types[]`; cli: `--type`; csharp, go: `Types`) フィルターを渡します。

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true&types[]=agent.tool_use&types[]=agent.tool_result" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01"
  ```

  ```bash CLI
  ant beta:sessions:events list --session-id "$SESSION_ID" \
    --type agent.tool_use --type agent.tool_result \
    --format jsonl
  ```

  ```python Python
  events = client.beta.sessions.events.list(
      session.id,
      types=["agent.tool_use", "agent.tool_result"],
  )
  for event in events.data:
      print(f"[{event.type}] {event.processed_at}")
  ```

  ```typescript TypeScript
  const events = await client.beta.sessions.events.list(session.id, {
    types: ["agent.tool_use", "agent.tool_result"]
  });
  for (const event of events.data) {
    console.log(`[${event.type}] ${event.processed_at}`);
  }
  ```

  ```csharp C#
  var events = await client.Beta.Sessions.Events.List(session.ID, new()
  {
      Types = ["agent.tool_use", "agent.tool_result"],
  });
  foreach (var sessionEvent in events.Items)
  {
      Console.WriteLine($"[{sessionEvent.Json.GetProperty("type").GetString()}] {sessionEvent.ProcessedAt}");
  }
  ```

  ```go Go
  events, err := client.Beta.Sessions.Events.List(ctx, session.ID, anthropic.BetaSessionEventListParams{
  	Types: []anthropic.BetaManagedAgentsSessionEventType{
  		anthropic.BetaManagedAgentsSessionEventTypeAgentToolUse,
  		anthropic.BetaManagedAgentsSessionEventTypeAgentToolResult,
  	},
  })
  if err != nil {
  	panic(err)
  }
  for _, event := range events.Data {
  	fmt.Printf("[%s] %s\n", event.Type, event.ProcessedAt)
  }
  ```

  ```java Java
  var events = client.beta().sessions().events().list(
      session.id(),
      EventListParams.builder()
          .addType(BetaManagedAgentsSessionEventType.AGENT_TOOL_USE)
          .addType(BetaManagedAgentsSessionEventType.AGENT_TOOL_RESULT)
          .build());
  for (var event : events.data()) {
      event.agentToolUse().ifPresent(toolUse ->
          IO.println("[" + toolUse.type() + "] " + toolUse.processedAt()));
      event.agentToolResult().ifPresent(toolResult ->
          IO.println("[" + toolResult.type() + "] " + toolResult.processedAt()));
  }
  ```

  ```php PHP
  $events = $client->beta->sessions->events->list(
      $session->id,
      types: ['agent.tool_use', 'agent.tool_result'],
  );
  foreach ($events->data as $event) {
      $processedAt = ($event->processedAt ?? null)?->format(DATE_RFC3339) ?? 'null';
      echo "[{$event->type}] {$processedAt}\n";
  }
  ```

  ```ruby Ruby
  events = client.beta.sessions.events.list(
    session.id,
    types: ["agent.tool_use", "agent.tool_result"]
  )
  events.data.each { puts "[#{it.type}] #{it.processed_at}" }
  ```
</CodeGroup>

## システムメッセージを送信する

[サポートされているモデル](https://platform.claude.com/docs/ja/managed-agents/events-and-streaming#supported-models)では、`system.message` イベントを送信して、エージェントに特権的なシステムレベルのコンテキストを与えることができます。このコンテキストは、付随するターンとそれ以降のすべてのターンに適用されます。異なるペルソナ、改訂された制約、実行時に取得したコンテキストなど、セッションの途中でエージェントに更新されたシステムレベルのガイダンスが必要な場合に使用します。

イベントの `content` (csharp, go: `Content`) は1〜1000個のテキスト項目を受け付けます。コンテンツは `role: "system"` ターンとしてセッションのシステムコンテキストに追加されます。これは、エージェント定義の `system` (csharp, go: `System`; ruby: `system_`) フィールドで設定されるトップレベルの「system prompt」（システムプロンプト）を置き換えるものではありません。

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions/$SESSION_ID/events?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d '{
      "events": [
        {
          "type": "system.message",
          "content": [
            {"type": "text", "text": "The current timezone of the user is America/New_York."}
          ]
        }
      ]
    }'
  ```

  ```bash CLI
  ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
  events:
    - type: system.message
      content:
        - type: text
          text: "The user's current timezone is America/New_York."
  YAML
  ```

  ```python Python
  client.beta.sessions.events.send(
      session.id,
      events=[
          {
              "type": "system.message",
              "content": [
                  {
                      "type": "text",
                      "text": "The user's current timezone is America/New_York.",
                  },
              ],
          },
      ],
  )
  ```

  ```typescript TypeScript
  await client.beta.sessions.events.send(session.id, {
    events: [
      {
        type: "system.message",
        content: [
          {
            type: "text",
            text: "The user's current timezone is America/New_York."
          }
        ]
      }
    ]
  });
  ```

  ```csharp C#
  await client.Beta.Sessions.Events.Send(session.ID, new()
  {
      Events =
      [
          new BetaManagedAgentsSystemMessageEventParams
          {
              Type = BetaManagedAgentsSystemMessageEventParamsType.SystemMessage,
              Content =
              [
                  new BetaManagedAgentsSystemContentBlock
                  {
                      Type = BetaManagedAgentsSystemContentBlockType.Text,
                      Text = "The user's current timezone is America/New_York.",
                  },
              ],
          },
      ],
  });
  ```

  ```go Go
  if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  	Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  		OfSystemMessage: &anthropic.BetaManagedAgentsSystemMessageEventParams{
  			Type: anthropic.BetaManagedAgentsSystemMessageEventParamsTypeSystemMessage,
  			Content: []anthropic.BetaManagedAgentsSystemContentBlockParam{{
  				Type: anthropic.BetaManagedAgentsSystemContentBlockTypeText,
  				Text: "The user's current timezone is America/New_York.",
  			}},
  		},
  	}},
  }); err != nil {
  	panic(err)
  }
  ```

  ```java Java
  client.beta().sessions().events().send(
      session.id(),
      EventSendParams.builder()
          .addEvent(BetaManagedAgentsSystemMessageEventParams.builder()
              .type(BetaManagedAgentsSystemMessageEventParams.Type.SYSTEM_MESSAGE)
              .addTextContent("The user's current timezone is America/New_York.")
              .build())
          .build());
  ```

  ```php PHP
  $client->beta->sessions->events->send(
      $session->id,
      events: [
          [
              'type' => 'system.message',
              'content' => [
                  [
                      'type' => 'text',
                      'text' => "The user's current timezone is America/New_York.",
                  ],
              ],
          ],
      ],
  );
  ```

  ```ruby Ruby
  client.beta.sessions.events.send_(
    session.id,
    events: [
      {
        type: "system.message",
        content: [
          {type: "text", text: "The user's current timezone is America/New_York."}
        ]
      }
    ]
  )
  ```
</CodeGroup>

### サポートされているモデル

`system.message` は次のモデルでサポートされています。

* Claude Fable 5.1
* Claude Mythos 5.1
* Claude Fable 5
* Claude Mythos 5
* Claude Opus 5.5
* Claude Opus 5
* Claude Opus 4.8
* Claude Sonnet 5.5
* Claude Haiku 5.5

エージェントのプライマリモデルが会話途中のシステム挿入をサポートしていない場合、イベントは `model_does_not_support_mid_conversation_system` 検証エラーで拒否されます。`system.message` はプライマリスレッドにのみ届くため、サブエージェントのモデルはチェックされません。

### ツール呼び出しが保留中のシステムメッセージ

セッションが `requires_action` の停止理由でアイドル状態の間、`system.message` は同じリクエスト内でツール結果イベントの後に続ける必要があります。単独で、または `user.message` とともに送信した場合、保留中のツールイベントが解決されるまで拒否されます。

## 次のステップ

<CardGroup cols={2}>
  <Card title="イベントデルタでレスポンスをプレビューする" icon="text" href="https://platform.claude.com/docs/ja/managed-agents/event-deltas">
    モデルがまだ生成している間に、エージェントのレスポンステキストをレンダリングします。
  </Card>

  <Card title="セッションを検査して使用量を追跡する" icon="magnifying-glass" href="https://platform.claude.com/docs/ja/managed-agents/session-observability">
    Claude Consoleでセッションを検査し、そのトークン使用量と定価コストを確認します。
  </Card>

  <Card title="Webhookをサブスクライブする" icon="link" href="https://platform.claude.com/docs/ja/managed-agents/webhooks">
    ポーリングせずに、主要なイベントが発生したときに通知を受け取ります。
  </Card>

  <Card title="イベントタイプ" icon="book" href="https://platform.claude.com/docs/ja/managed-agents/reference#event-types">
    セッションが送受信できるすべてのイベントタイプを確認します。
  </Card>
</CardGroup>
