# APIサンプルコード

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

※ 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秒以上）に設定することを推奨します。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.digitalhumans.jp/dify-guide/appendix/dify-docs-api-sample-code.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
