> For the complete documentation index, see [llms.txt](https://docs.digitalhumans.jp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.digitalhumans.jp/dify-guide/appendix/dify-docs-api-sample-code.md).

# APIサンプルコード

{% hint style="warning" %}
**利用上の注意**\
本ドキュメントは Dify Cloud版 (`https://api.dify.ai`) を想定しています。セルフホスト版を利用される場合は、ベースURLをご自身の環境に合わせて変更してください。

※ BASE\_URL には API Base URL を設定してください。DHKK 環境をご利用の場合は、DHKK\
またはご担当のパートナー・リセラーにご確認ください。

APIの仕様はアップデートにより変更される可能性があります。本番運用前には必ず [Dify 公式ドキュメント](https://docs.dify.ai/) も併せてご確認ください。
{% endhint %}

## 1. 事前準備

1. Dify管理画面で対象のアプリケーションを開く。
2. 左側メニューの **「APIアクセス」** をクリック。
3. 右上の **「APIキー」** をクリックしてキーを生成・コピーする。

## 2. APIの基本仕様

* **エンドポイント**: `POST /v1/chat-messages`
* **ヘッダー**:
  * `Authorization: Bearer {YOUR_API_KEY}`
  * `Content-Type: application/json`

### リクエストパラメータ

| パラメータ名            | 型      | 必須  | 説明                                    |
| ----------------- | ------ | --- | ------------------------------------- |
| `query`           | string | Yes | ユーザーからの入力テキスト                         |
| `user`            | string | Yes | ユーザー識別子（開発者側で定義する一意のID）               |
| `response_mode`   | string | Yes | `blocking`（一括返信）または `streaming`（逐次返信） |
| `inputs`          | object | Yes | プロンプト内の変数（変数がなければ空のオブジェクト`{}`で可）      |
| `conversation_id` | string | No  | 会話を継続する場合に指定（初回は未指定）                  |

## 3. 基本的なAPI呼び出し（Blocking）

`response_mode: "blocking"` は、AIの生成完了を待ってからレスポンスを一括で受け取る方式です。実装が単純で、音声合成（TTS）などと連携する場合に適しています。

### 3.1 cURL

```bash
curl -X POST 'https://api.dify.ai/v1/chat-messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "inputs": {},
    "query": "こんにちは、営業時間を教えてください",
    "response_mode": "blocking",
    "user": "user-123"
  }'
```

### 3.2 Python (requests)

```python
import requests

def chat_with_dify(query, user_id, conversation_id=None, api_key="YOUR_API_KEY"):
    base_url = "https://api.dify.ai/v1/chat-messages"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    payload = {
        "inputs": {},  # プロンプト変数がある場合はここに設定
        "query": query,
        "response_mode": "blocking",
        "user": user_id,
    }
    if conversation_id:
        payload["conversation_id"] = conversation_id

    try:
        response = requests.post(base_url, headers=headers, json=payload, timeout=60)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")
        return None

# 使用例
result = chat_with_dify(
    query="営業時間を教えてください",
    user_id="user-123"
)

if result:
    print("Answer:", result.get("answer"))
    print("Conversation ID:", result.get("conversation_id"))
```

### 3.3 JavaScript (Node.js / axios)

```jsx
const axios = require('axios');

async function chatWithDify(query, userId, conversationId = null, apiKey = 'YOUR_API_KEY') {
  const url = 'https://api.dify.ai/v1/chat-messages';
  const payload = {
    inputs: {},
    query: query,
    response_mode: 'blocking',
    user: userId
  };

  if (conversationId) {
    payload.conversation_id = conversationId;
  }

  try {
    const response = await axios.post(url, payload, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      timeout: 60000 // 60秒タイムアウト
    });
    return response.data;
  } catch (error) {
    console.error('API Error:', error.response ? error.response.data : error.message);
    throw error;
  }
}

// 使用例
(async () => {
  try {
    const result = await chatWithDify('営業時間を教えてください', 'user-123');
    console.log('Answer:', result.answer);
  } catch (e) {
    // エラーハンドリング
  }
})();
```

## 4. ストリーミングレスポンス（Streaming）

`response_mode: "streaming"` は、応答を逐次受け取る方式です。UXを向上させる（文字が打たれるように表示する）場合に利用します。 レスポンスは Server-Sent Events (SSE) 形式で返却されます。

### 4.1 Python（Streaming処理の例）

```python
  import requests
  import json

  def chat_streaming(query, user_id, api_key="YOUR_API_KEY"):
      url = "https://api.dify.ai/v1/chat-messages"
      headers = {
          "Authorization": f"Bearer {api_key}",
          "Content-Type": "application/json",
      }
      payload = {
          "inputs": {},
          "query": query,
          "response_mode": "streaming",
          "user": user_id,
      }

      print("Bot: ", end="", flush=True)

      with requests.post(url, headers=headers, json=payload, stream=True, timeout=60) as response:
          response.raise_for_status()
          for line in response.iter_lines(decode_unicode=True):
              if line and line.startswith("data:"):
                  # "data: " のプレフィックスを除去してJSONパース
                  json_str = line[5:].strip()
                  try:
                      data = json.loads(json_str)
                      event = data.get("event")

                      # メッセージ終了またはエラー時
                      if event in ["message_end", "error"]:
                          break

                      # テキスト生成イベントの場合
                      if event == "message":
                          answer = data.get("answer", "")
                          print(answer, end="", flush=True)

                  except json.JSONDecodeError:
                      continue
      print() # 改行

  # 使用例
  chat_streaming("Difyについて教えて", "user-123")
```

## 5. レスポンスフィールドの例

### 成功時 (Blocking Mode)

```json
{
  "event": "message",
  "message_id": "9dbbb6c1-c88f-43b3-8c4c-2f222830e236",
  "conversation_id": "e56b4028-0955-460d-88b9-11221375e236",
  "mode": "chat",
  "answer": "DifyはオープンソースのLLMアプリ開発プラットフォームです...",
  "metadata": { ... },
  "created_at": 1705627476
}
```

### エラー時

```json
{
  "code": "invalid_api_key",
  "message": "Invalid API key",
  "status": 401
}
```

## 6. デジタルヒューマン・外部連携のポイント

デジタルヒューマンや音声アシスタントと連携する場合の推奨設計です。

1. **Blocking Modeの推奨**: `response_mode: "blocking"`を使用することで、完全な文章を取得してからTTS（音声合成）エンジンに渡すことができます。これにより、音声の途切れを防げます。
2. **Conversation IDの管理**: レスポンスに含まれる`conversation_id`を保存し、次回のAPIリクエストに含めることで、文脈（コンテキスト）を維持した会話が可能になります。
3. **タイムアウト設定**: LLMの生成には時間がかかる場合があるため、クライアント側のタイムアウト設定（`timeout`）は長め（例: 60秒以上）に設定することを推奨します。
