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

# WebSocket API

WebSocket 経由でアプリケーションと音声エージェントの間で音声をストリーミングします。Web アプリ、モバイルアプリ、または独自のテレフォニープロバイダーをブリッジするのに使用できます。

## クイックスタート

```javascript theme={null}
const ws = new WebSocket(
  `wss://api.cartesia.ai/agents/stream/${agentId}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Cartesia-Version": "2025-04-16",
    },
  }
);

// Initialize the stream
ws.onopen = () => {
  ws.send(JSON.stringify({
    event: "start",
    config: { input_format: "pcm_44100" },
  }));
};

// Handle agent audio
ws.onmessage = (msg) => {
  const data = JSON.parse(msg.data);
  if (data.event === "media_output") {
    playAudio(atob(data.media.payload));
  }
};

// Send user audio
function sendAudio(audioData) {
  ws.send(JSON.stringify({
    event: "media_input",
    stream_id: streamId,
    media: { payload: btoa(audioData) },
  }));
}
```

`/access-token` [エンドポイント](/api-reference/auth/access-token#body-grants-agent) からアクセストークンを取得します。詳細は [クライアントアプリの認証](/get-started/authenticate-your-client-applications) を参照してください。

***

## 接続

WebSocket エンドポイントに接続します：

```
wss://api.cartesia.ai/agents/stream/{agent_id}
```

**ヘッダー:**

| ヘッダー               | 値                |
| ------------------ | ---------------- |
| `Authorization`    | `Bearer {token}` |
| `Cartesia-Version` | `2025-04-16`     |

## プロトコル概要

WebSocket 接続は、制御イベントには JSON メッセージ、メディアには Base64 エンコードされた音声を使用します。

クライアントが `start` イベントを送信すると、サーバーは `ack` で応答します。その後、両者は接続が閉じるまで音声と制御イベントを交換します。

## クライアントイベント

### Start イベント

音声ストリームの構成を初期化します。

* `config` はエージェントのデフォルトの入力音声設定を上書きします
* `stream_id` は任意です。指定されない場合、サーバーが生成して `ack` イベントで返します

**これは最初に送信するメッセージである必要があります。**

```json theme={null}
{
  "event": "start",
  "stream_id": "unique_id",
  "config": {
    "input_format": "pcm_44100",
    "voice_id": "a0e99841-438c-4a64-b679-ae501e7d6091"
  },
  "agent": {
    "introduction": "Hello, I'm an AI assistant",
    "system_prompt": "### Your Role \n You are a helpful assistant"
  },
  "metadata": {
    "to": "user@example.com",
    "from": "+1234567890"
  }
}
```

**フィールド:**

* `stream_id`（任意）: ストリーム識別子。指定されない場合はサーバーが生成
* `config.input_format`: クライアント音声入力の音声形式（`mulaw_8000`、`pcm_16000`、`pcm_24000`、`pcm_44100`）
* `config.voice_id`（任意）: エージェントのデフォルト TTS ボイスを上書き
* `agent`（任意）: API 経由で個別のエージェント通話を構成し、本番環境に公開せずに introduction やプロンプトの変更をプレビュー可能
* `metadata`（任意）: カスタムメタデータオブジェクト。これらはエージェントコードに渡されますが、特別なフィールドも使用できます：
  * `to`（任意）: コールルーティング用の宛先識別子（デフォルトはエージェント ID）
  * `from`（任意）: 通話の発信元識別子（デフォルトは「websocket」）

### Media Input イベント

クライアントからサーバーに送信される音声データです。`payload` の音声データは Base64 エンコードする必要があります。

```json theme={null}
{
  "event": "media_input",
  "stream_id": "unique_id",
  "media": {
    "payload": "base64_encoded_audio_data"
  }
}
```

**フィールド:**

* `stream_id`: ack レスポンスから取得したストリームの一意の識別子
* `media.payload`: start イベントで指定された形式の Base64 エンコードされた音声データ

### DTMF イベント

DTMF（デュアルトーン多重周波数）トーンを送信します。

```json theme={null}
{
\u0001\u0001\u0001  "event": "dtmf",
  "stream_id": "example_id",
  "dtmf": "1"
}
```

**フィールド:**

* `stream_id`: ストリーム識別子
* `dtmf`: DTMF 桁（0〜9、\*、#）

### Custom イベント

エージェントにカスタムメタデータを送信します。

```json theme={null}
{
  "event": "custom",
  "stream_id": "example_id",
  "metadata": {
    "user_id": "user123",
    "session_info": "custom_data"
  }
}
```

**フィールド:**

* `stream_id`: ストリーム識別子
* `metadata`: カスタムデータのキーと値のペアを含むオブジェクト

## サーバーイベント

### Ack イベント

ストリーム構成を確認します。`start` イベントで `stream_id` が指定されなかった場合、サーバーが生成した `stream_id` を返します。

```json theme={null}
{
  "event": "ack",
  "stream_id": "example_id",
  "config": {
    "input_format": "pcm_44100",
    "voice_id": "a0e99841-438c-4a64-b679-ae501e7d6091"
  },
  "agent": {
    "system_prompt": "### Your Role \n You are a helpful assistant",
    "introduction": "Hello, I'm an AI assistant"
  }
}
```

### Media Output イベント

サーバーがエージェントの音声レスポンスを送信します。`payload` は Base64 エンコードされた音声データです。

```json theme={null}
{
  "event": "media_output",
  "stream_id": "example_id",
  "media": {
    "payload": "base64_encoded_audio_data"
  }
}
```

### Clear イベント

エージェントが現在の音声ストリームをクリア／中断したいことを示します。

```json theme={null}
{
  "event": "clear",
  "stream_id": "example_id"
}
```

### Transfer Call イベント

エージェントが通話を電話番号に転送したいことを示します。クライアントは自身のテレフォニー側で転送を開始する責任があります。

```json theme={null}
{
  "event": "transfer_call",
  "stream_id": "example_id",
  "transfer": {
    "target_phone_number": "+1234567890"
  }
}
```

**フィールド:**

* `stream_id`: ストリーム識別子
* `transfer.target_phone_number`: 通話を転送する E.164 形式の電話番号

## 接続の管理

### 無操作タイムアウト

サーバーは **180 秒** 後にアイドル接続を閉じます。クライアントからのメッセージがあるたびにタイマーがリセットされます：

* アプリケーションメッセージ（media\_input、dtmf、custom イベント）
* 標準の WebSocket ping フレーム
* その他の有効な WebSocket メッセージ

タイムアウトが発生すると、接続は次のように閉じられます：

* **コード:** 1000（Normal Closure）
* **理由:** `"connection idle timeout"`

### Ping/Pong キープアライブ

無音期間中の無操作タイムアウトを防ぐため、定期的なキープアライブとして標準の WebSocket ping フレームを使用します：

```python theme={null}
# Client sends ping to reset inactivity timer
pong_waiter = await websocket.ping()
latency = await pong_waiter
```

```javascript theme={null}
// Requires the Node.js `ws` library — the browser WebSocket API does not expose ping()
setInterval(() => {
  if (websocket.readyState === WebSocket.OPEN) {
    websocket.ping();
  }
}, 60000); // Send ping every 60 seconds
```

サーバーは ping フレームに自動的に pong フレームで応答し、いずれかのメッセージを受信すると無操作タイマーをリセットします。

### 接続の終了

接続はクライアントまたはサーバーのどちらからでも WebSocket クローズフレームを使って閉じることができます。

**クライアント開始のクローズ:**

```python theme={null}
await websocket.close(code=1000, reason="session completed")
```

**サーバー開始のクローズ:**
エージェントが通話を終了すると、サーバーは次のように接続を閉じます：

* **コード:** 1000（Normal Closure）
* **理由:** `"call ended by agent"` または、追加のコンテキストが利用可能な場合は `"call ended by agent, reason: {specific_reason}"`

## ベストプラクティス

1. **最初に `start` を送信** — `start` より前に他のイベントが送信されると接続は閉じられます。
2. **適切な音声形式を選択** — ソースに合わせて形式を選択してください：テレフォニーには `mulaw_8000`、Web クライアントには `pcm_44100`。
3. **クローズを適切に処理** — デバッグやリカバリのため、常にクローズコードと理由をキャプチャしてください。
4. **接続を維持** — 180 秒の無操作タイムアウトを回避するため、60〜90 秒ごとに WebSocket ping フレームを送信してください。
5. **ストリーム ID を管理** — システム全体のオブザーバビリティを高めるため、独自の `stream_id` 値を指定してください。
6. **アイドルタイムアウトから復旧** — `1000 / connection idle timeout` の場合、再接続して `start` イベントを再送してください。
