A plugin can reverse invoke an App within Dify to access its data, with both streaming and non-streaming calls. If you are unfamiliar with the basics of reverse invocation, first read Reverse Invocation of Dify Services.
Interface Types:
- Chat Interface:
Chatbot, Agent, and Chatflow applications are all chat-based and share the same input and output parameter types, so they share this interface.
- Workflow Interface: Used by Workflow applications.
- Completion Interface: Used by Completion (text generation) applications.
Plugins can only access Apps within the Workspace where the plugin resides.
Call the Chat Interface
Entry Point
Interface Specification
def invoke(
self,
app_id: str,
inputs: dict,
response_mode: Literal["streaming", "blocking"],
conversation_id: str,
files: list,
) -> Generator[dict, None, None] | dict:
pass
When response_mode is streaming, this interface returns Generator[dict]; otherwise it returns dict. For the specific interface fields, see the return results of ServiceApi.
Use Case
This example calls a Chat type App within an Endpoint and returns the result directly:
import json
from typing import Mapping
from werkzeug import Request, Response
from dify_plugin import Endpoint
class Duck(Endpoint):
def _invoke(self, r: Request, values: Mapping, settings: Mapping) -> Response:
"""
Invokes the endpoint with the given request.
"""
app_id = values["app_id"]
def generator():
response = self.session.app.chat.invoke(
app_id=app_id,
inputs={},
response_mode="streaming",
conversation_id="some-conversation-id",
files=[],
)
for data in response:
yield f"{json.dumps(data)} <br>"
return Response(generator(), status=200, content_type="text/html")
Call the Workflow Interface
Entry Point
self.session.app.workflow
Interface Specification
def invoke(
self,
app_id: str,
inputs: dict,
response_mode: Literal["streaming", "blocking"],
files: list,
) -> Generator[dict, None, None] | dict:
pass
Call the Completion Interface
Entry Point
self.session.app.completion
Interface Specification
def invoke(
self,
app_id: str,
inputs: dict,
response_mode: Literal["streaming", "blocking"],
files: list,
) -> Generator[dict, None, None] | dict:
pass
Last modified on June 24, 2026