Dify の API エンドポイント徹底解説:外部連携の基本

現代の AI 技術は目覚ましい発展を遂げており、ChatGPT や Claude、Gemini といった大規模言語モデル(LLM)がビジネスの現場で活用されるようになりました。しかし、これらの AI 技術を既存のシステムや新しいアプリケーションに組み込む際、多くの開発者が直面するのが「外部連携」の課題です。
Dify は、AI アプリケーション開発プラットフォームとして、豊富な API エンドポイントを提供し、外部システムとのシームレスな連携を可能にします。本記事では、Dify API の基本から実践的な実装方法まで、初心者の方にも理解しやすい形で徹底解説いたします。
背景
従来の AI アプリ連携の課題
これまでの AI アプリケーション開発において、外部システムとの連携は非常に複雑で時間のかかる作業でした。
従来の開発では以下のような課題がありました:
- 認証システムの複雑さ:各 AI サービスごとに異なる認証方式への対応
- データ形式の統一困難:サービス間でのデータフォーマットの違い
- リアルタイム処理の実装負荷:WebSocket や SSE の実装コスト
- エラーハンドリングの複雑性:各 API の仕様に合わせた例外処理
これらの課題により、多くの開発プロジェクトで予想以上の開発期間とコストが発生していました。
Dify の API 設計思想
Dify は、これらの従来の課題を解決するため、以下の設計思想に基づいて API を構築しています。
統一性と一貫性 すべての API エンドポイントで一貫した命名規則とレスポンス形式を採用し、学習コストを最小限に抑えています。
拡張性とモジュラー設計 機能ごとに API が分離されており、必要な機能のみを選択して利用できる柔軟な設計となっています。
開発者ファーストなアプローチ 詳細なドキュメントと豊富なサンプルコードにより、迅速な開発開始を支援します。
RESTful API の基本概念
Dify の API は、RESTful 設計原則に従って構築されています。RESTful API の基本的な概念を理解することで、より効果的に Dify API を活用できます。
| # | HTTP メソッド | 用途 | 例 | 
|---|---|---|---|
| 1 | GET | データの取得 | アプリ一覧の取得 | 
| 2 | POST | データの作成 | 新しい会話の開始 | 
| 3 | PUT | データの更新 | アプリ設定の変更 | 
| 4 | DELETE | データの削除 | 会話の削除 | 
Dify API の全体像
API エンドポイントの種類と分類
Dify API は、機能別に以下のカテゴリに分類されています。
アプリケーション管理系 API
- アプリの作成、編集、削除
- アプリ設定の管理
- バージョン管理
会話・チャット系 API
- 会話の開始と管理
- メッセージの送受信
- ストリーミング応答
ファイル・ナレッジベース系 API
- ファイルのアップロード
- ナレッジベースの管理
- 文書の検索
ユーザー・認証系 API
- ユーザー管理
- 認証トークン管理
- アクセス権限制御
認証方式の理解
Dify API では、セキュアな認証方式を採用しています。
API キー認証 最も基本的な認証方式で、HTTP ヘッダーに API キーを含めてリクエストを送信します。
typescriptconst headers = {
  Authorization: 'Bearer YOUR_API_KEY',
  'Content-Type': 'application/json',
};
この認証方式により、不正アクセスを防ぎつつ、シンプルな実装を可能にしています。
アクセス制御の仕組み API キーには、スコープと呼ばれる権限設定が含まれており、特定の機能のみにアクセスを制限できます。
レスポンス形式の基本構造
Dify API のレスポンスは、統一された構造を持っています。
json{
  "status": "success",
  "data": {
    // 実際のデータ
  },
  "message": "操作が正常に完了しました",
  "timestamp": "2024-01-01T00:00:00Z"
}
エラー時のレスポンス構造も一貫しており、効率的なエラーハンドリングが可能です。
json{
  "status": "error",
  "error": {
    "code": "INVALID_PARAMETER",
    "message": "パラメータが正しくありません",
    "details": "email フィールドが必須です"
  },
  "timestamp": "2024-01-01T00:00:00Z"
}
基本的な API 操作
アプリケーション管理 API
アプリケーション管理 API は、Dify アプリの基本的な操作を提供します。
アプリ一覧の取得 以下のコードで、現在利用可能なアプリの一覧を取得できます。
typescriptasync function getApplications() {
  const response = await fetch(
    'https://api.dify.ai/v1/apps',
    {
      method: 'GET',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
    }
  );
  const data = await response.json();
  return data;
}
この API を使用することで、動的にアプリ選択機能を実装できます。
新しいアプリの作成 プログラムからアプリを作成する際は、以下のようなパラメータを指定します。
typescriptasync function createApplication(appData: {
  name: string;
  description: string;
  template: string;
}) {
  const response = await fetch(
    'https://api.dify.ai/v1/apps',
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(appData),
    }
  );
  return await response.json();
}
この機能により、テンプレートからアプリを自動生成するシステムを構築できます。
会話管理 API
会話管理 API は、チャットボットや AI アシスタントの核となる機能です。
新しい会話の開始 会話を開始する際は、まず会話セッションを作成します。
typescriptasync function startConversation(
  appId: string,
  userId: string
) {
  const response = await fetch(
    `https://api.dify.ai/v1/apps/${appId}/conversations`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        user_id: userId,
        inputs: {},
      }),
    }
  );
  return await response.json();
}
メッセージの送信と応答取得 作成した会話セッションに対してメッセージを送信し、AI からの応答を取得します。
typescriptasync function sendMessage(
  appId: string,
  conversationId: string,
  message: string,
  userId: string
) {
  const response = await fetch(
    `https://api.dify.ai/v1/apps/${appId}/conversations/${conversationId}/messages`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        query: message,
        user_id: userId,
        response_mode: 'blocking',
      }),
    }
  );
  return await response.json();
}
この API により、リアルタイムなチャット機能を簡単に実装できます。
ファイル管理 API
ファイル管理 API は、ドキュメントや画像などのファイルをアップロードし、ナレッジベースとして活用する機能を提供します。
ファイルのアップロード 以下のコードで、ファイルを Dify にアップロードできます。
typescriptasync function uploadFile(file: File) {
  const formData = new FormData();
  formData.append('file', file);
  const response = await fetch(
    'https://api.dify.ai/v1/files/upload',
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
      },
      body: formData,
    }
  );
  return await response.json();
}
ファイル情報の取得 アップロードしたファイルの詳細情報を取得する際は、以下の API を使用します。
typescriptasync function getFileInfo(fileId: string) {
  const response = await fetch(
    `https://api.dify.ai/v1/files/${fileId}`,
    {
      method: 'GET',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
    }
  );
  return await response.json();
}
これらの API により、ファイルベースの RAG(Retrieval-Augmented Generation)システムを構築できます。
ユーザー管理 API
ユーザー管理 API は、マルチユーザー対応のアプリケーションを構築する際に重要な機能です。
ユーザーの作成 新しいユーザーをシステムに登録する際は、以下の API を使用します。
typescriptasync function createUser(userData: {
  user_id: string;
  name: string;
  email: string;
}) {
  const response = await fetch(
    'https://api.dify.ai/v1/users',
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(userData),
    }
  );
  return await response.json();
}
ユーザー情報の取得 特定のユーザーの情報を取得する際は、以下のように API を呼び出します。
typescriptasync function getUserInfo(userId: string) {
  const response = await fetch(
    `https://api.dify.ai/v1/users/${userId}`,
    {
      method: 'GET',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
    }
  );
  return await response.json();
}
これらの機能により、ユーザーごとに個別化された AI 体験を提供できます。
実践的な外部連携実装
Node.js での基本実装
Node.js で Dify API を活用する基本的な実装方法をご紹介します。
プロジェクトの初期化 まず、新しい Node.js プロジェクトを作成し、必要なパッケージをインストールします。
bashyarn init -y
yarn add express typescript @types/node @types/express
yarn add -D nodemon ts-node
基本的な API クライアントクラス Dify API との通信を管理するクライアントクラスを作成します。
typescriptclass DifyAPIClient {
  private apiKey: string;
  private baseURL: string;
  constructor(
    apiKey: string,
    baseURL = 'https://api.dify.ai/v1'
  ) {
    this.apiKey = apiKey;
    this.baseURL = baseURL;
  }
  private async request(
    endpoint: string,
    options: RequestInit = {}
  ) {
    const url = `${this.baseURL}${endpoint}`;
    const headers = {
      Authorization: `Bearer ${this.apiKey}`,
      'Content-Type': 'application/json',
      ...options.headers,
    };
    const response = await fetch(url, {
      ...options,
      headers,
    });
    if (!response.ok) {
      throw new Error(
        `API request failed: ${response.statusText}`
      );
    }
    return await response.json();
  }
  async getApplications() {
    return await this.request('/apps');
  }
  async createConversation(appId: string, userId: string) {
    return await this.request(
      `/apps/${appId}/conversations`,
      {
        method: 'POST',
        body: JSON.stringify({
          user_id: userId,
          inputs: {},
        }),
      }
    );
  }
  async sendMessage(
    appId: string,
    conversationId: string,
    message: string,
    userId: string
  ) {
    return await this.request(
      `/apps/${appId}/conversations/${conversationId}/messages`,
      {
        method: 'POST',
        body: JSON.stringify({
          query: message,
          user_id: userId,
          response_mode: 'blocking',
        }),
      }
    );
  }
}
このクライアントクラスにより、型安全で再利用可能な API 操作が可能になります。
React アプリとの連携
React アプリケーションで Dify API を活用する実装例をご紹介します。
カスタムフックの作成 API 操作を React コンポーネントで利用しやすくするため、カスタムフックを作成します。
typescriptimport { useState, useCallback } from 'react';
interface UseDifyAPIProps {
  apiKey: string;
  appId: string;
}
export const useDifyAPI = ({
  apiKey,
  appId,
}: UseDifyAPIProps) => {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const sendMessage = useCallback(
    async (
      message: string,
      userId: string,
      conversationId?: string
    ) => {
      setIsLoading(true);
      setError(null);
      try {
        // 会話IDがない場合は新しい会話を作成
        if (!conversationId) {
          const conversationResponse = await fetch(
            `https://api.dify.ai/v1/apps/${appId}/conversations`,
            {
              method: 'POST',
              headers: {
                Authorization: `Bearer ${apiKey}`,
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({
                user_id: userId,
                inputs: {},
              }),
            }
          );
          const conversationData =
            await conversationResponse.json();
          conversationId = conversationData.data.id;
        }
        // メッセージを送信
        const messageResponse = await fetch(
          `https://api.dify.ai/v1/apps/${appId}/conversations/${conversationId}/messages`,
          {
            method: 'POST',
            headers: {
              Authorization: `Bearer ${apiKey}`,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              query: message,
              user_id: userId,
              response_mode: 'blocking',
            }),
          }
        );
        const messageData = await messageResponse.json();
        return {
          response: messageData.data.answer,
          conversationId,
        };
      } catch (err) {
        const errorMessage =
          err instanceof Error
            ? err.message
            : '不明なエラーが発生しました';
        setError(errorMessage);
        throw err;
      } finally {
        setIsLoading(false);
      }
    },
    [apiKey, appId]
  );
  return { sendMessage, isLoading, error };
};
チャットコンポーネントの実装 作成したカスタムフックを使用して、実際のチャットインターフェースを構築します。
typescriptimport React, { useState } from 'react';
import { useDifyAPI } from './hooks/useDifyAPI';
interface Message {
  id: string;
  text: string;
  isUser: boolean;
  timestamp: Date;
}
export const ChatComponent: React.FC = () => {
  const [messages, setMessages] = useState<Message[]>([]);
  const [inputText, setInputText] = useState('');
  const [conversationId, setConversationId] =
    useState<string>('');
  const { sendMessage, isLoading, error } = useDifyAPI({
    apiKey: process.env.REACT_APP_DIFY_API_KEY!,
    appId: process.env.REACT_APP_DIFY_APP_ID!,
  });
  const handleSendMessage = async () => {
    if (!inputText.trim()) return;
    // ユーザーメッセージを追加
    const userMessage: Message = {
      id: Date.now().toString(),
      text: inputText,
      isUser: true,
      timestamp: new Date(),
    };
    setMessages((prev) => [...prev, userMessage]);
    setInputText('');
    try {
      const result = await sendMessage(
        inputText,
        'user123',
        conversationId
      );
      // 会話IDを保存
      if (!conversationId) {
        setConversationId(result.conversationId);
      }
      // AIの応答を追加
      const aiMessage: Message = {
        id: (Date.now() + 1).toString(),
        text: result.response,
        isUser: false,
        timestamp: new Date(),
      };
      setMessages((prev) => [...prev, aiMessage]);
    } catch (err) {
      console.error('メッセージの送信に失敗しました:', err);
    }
  };
  return (
    <div className='chat-container'>
      <div className='messages'>
        {messages.map((message) => (
          <div
            key={message.id}
            className={`message ${
              message.isUser ? 'user' : 'ai'
            }`}
          >
            <p>{message.text}</p>
            <small>
              {message.timestamp.toLocaleTimeString()}
            </small>
          </div>
        ))}
      </div>
      {error && (
        <div className='error-message'>エラー: {error}</div>
      )}
      <div className='input-section'>
        <input
          type='text'
          value={inputText}
          onChange={(e) => setInputText(e.target.value)}
          onKeyPress={(e) =>
            e.key === 'Enter' && handleSendMessage()
          }
          disabled={isLoading}
          placeholder='メッセージを入力してください...'
        />
        <button
          onClick={handleSendMessage}
          disabled={isLoading || !inputText.trim()}
        >
          {isLoading ? '送信中...' : '送信'}
        </button>
      </div>
    </div>
  );
};
この実装により、React アプリに本格的な AI チャット機能を簡単に組み込むことができます。
Webhook の活用方法
Webhook は、Dify からの非同期通知を受け取るための仕組みです。
Webhook エンドポイントの作成 Express.js で Webhook を受信するエンドポイントを作成します。
typescriptimport express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json());
// Webhookの署名検証
function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}
// Webhook受信エンドポイント
app.post('/webhook/dify', (req, res) => {
  const signature = req.headers[
    'x-dify-signature'
  ] as string;
  const payload = JSON.stringify(req.body);
  // 署名を検証
  if (
    !verifyWebhookSignature(
      payload,
      signature,
      process.env.WEBHOOK_SECRET!
    )
  ) {
    return res
      .status(401)
      .json({ error: 'Invalid signature' });
  }
  const event = req.body;
  switch (event.type) {
    case 'conversation.completed':
      handleConversationCompleted(event.data);
      break;
    case 'message.created':
      handleMessageCreated(event.data);
      break;
    case 'workflow.completed':
      handleWorkflowCompleted(event.data);
      break;
    default:
      console.log('Unknown event type:', event.type);
  }
  res.status(200).json({ status: 'received' });
});
// イベントハンドラーの実装
function handleConversationCompleted(data: any) {
  console.log('会話が完了しました:', data);
  // 必要な後処理を実装
  // 例:データベースへの保存、メール通知など
}
function handleMessageCreated(data: any) {
  console.log('新しいメッセージが作成されました:', data);
  // リアルタイム通知の送信など
}
function handleWorkflowCompleted(data: any) {
  console.log('ワークフローが完了しました:', data);
  // 結果の処理やレポート生成など
}
app.listen(3000, () => {
  console.log('Webhook server is running on port 3000');
});
Webhook の設定 Dify 側で Webhook を設定する際は、以下のパラメータを指定します。
typescriptasync function setupWebhook(
  appId: string,
  webhookUrl: string
) {
  const response = await fetch(
    `https://api.dify.ai/v1/apps/${appId}/webhooks`,
    {
      method: 'POST',
      headers: {
        Authorization: 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        url: webhookUrl,
        events: [
          'conversation.completed',
          'message.created',
          'workflow.completed',
        ],
        secret: process.env.WEBHOOK_SECRET,
      }),
    }
  );
  return await response.json();
}
この設定により、Dify からの各種イベントをリアルタイムで受信し、適切な処理を実行できます。
まとめ
本記事では、Dify API エンドポイントの基本から実践的な外部連携実装まで、段階的に解説いたしました。
習得できた知識
- RESTful API の基本概念と Dify の設計思想
- 主要 API エンドポイントの使い方と実装方法
- Node.js と React での実践的な連携実装
- Webhook を活用したリアルタイム処理
Dify API の強力な機能を活用することで、従来の AI 連携で課題となっていた複雑性やコストの問題を大幅に軽減できます。統一された API インターフェースにより、学習コストを最小限に抑えながら、本格的な AI アプリケーションを構築することが可能です。
また、今回ご紹介したサンプルコードは、実際のプロジェクトでそのまま活用いただけるよう、エラーハンドリングやセキュリティ対策も含めて設計しております。これらをベースに、皆様の要件に合わせてカスタマイズしていただければと思います。
次のステップとして、より高度な機能である認証システムの実装やパフォーマンス最適化、マルチテナント対応などにも挑戦していただけると、さらに実用的な AI アプリケーションを構築できるでしょう。
関連リンク
 article article- Dify で実現する RAG 以外の戦略:ツール実行・関数呼び出し・自律エージェントの全体像
 article article- Dify 本番運用ガイド:SLO/SLA 設定とアラート設計のベストプラクティス
 article article- Dify 中心のドメイン駆動設計:ユースケースとフローの境界づけ
 article article- Dify プロンプト設計チートシート:役割宣言・制約・出力フォーマットの定石
 article article- Dify を macOS でローカル検証:Docker Compose で最短起動する手順
 article article- Dify と LangGraph/LangChain を比較:表現力・保守性・学習コストのリアル
 article article- MySQL ERROR 1449 対策:DEFINER 不明でビューやトリガーが壊れた時の復旧手順
 article article- Cursor で差分が崩れる/意図しない大量変更が入るときの復旧プレイブック
 article article- Motion(旧 Framer Motion)で exit が発火しない/遅延する問題の原因切り分けガイド
 article article- JavaScript 時刻の落とし穴大全:タイムゾーン/DST/うるう秒の実務対策
 article article- Cline が差分を誤適用する時:改行コード・Prettier・改フォーマット問題の解決
 article article- htmx で二重送信が起きる/起きない問題の完全対処:trigger と disable パターン
 blog blog- iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
 blog blog- Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
 blog blog- 【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
 blog blog- Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
 blog blog- Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
 blog blog- フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
 review review- 今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
 review review- ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
 review review- 愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
 review review- 週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
 review review- 新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
 review review- 科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来