Chat service interfaces provide complete chat functionality integration capabilities, including message sending and receiving, session management, voice conversion and other core functions. All interfaces require a valid API key for authentication. Use the DifyChat interface instance.
ChatMessageSendResponse send(ChatMessageSendRequest sendRequest);
ChatMessageSendRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| conversationId | String | No | Chat session number |
| content | String | Yes | Message content |
| files | List<ChatMessageFile> | No | file |
| inputs | Map<String, Object> | No | Customized parameters |
ChatMessageFile Structure:
| Parameter name | Type | Description |
|---|
| id | String | File ID |
| type | String | File type, default is "image" |
| url | String | Preview image URL |
| transferMethod | String | Transfer method, default is "remote_url" |
| belongsTo | String | File owner, user or assistant |
| uploadFileId | String | Upload file ID |
ChatMessageSendResponse
| Parameter name | Type | Description |
|---|
| conversationId | String | Chat session number |
| messageId | String | Message id |
| createdAt | Long | Creating timestamps |
| taskId | String | Task id |
| id | String | id |
| answer | String | answer |
Flux<ChatMessageSendCompletionResponse> sendChatMessageStream(ChatMessageSendRequest sendRequest);
Same as the Send Message interface
Returns a message stream with the following structure:
ChatMessageSendCompletionResponse
| Parameter name | Type | Description |
|---|
| workflowRunId | String | Workflow run ID |
| data | CompletionData | Completion data, varies by event type |
The CompletionData structure varies depending on the event type:
| Event Type | Description | Corresponding Data Class |
|---|
| workflow_started | Workflow started | WorkflowStartedData |
| node_started | Node started | NodeStartedData |
| node_finished | Node finished | NodeFinishedData |
| workflow_finished | Workflow finished | WorkflowFinishedData |
void stopMessagesStream(String apiKey, String taskId, String userId);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| taskId | String | Yes | taskId |
| userId | String | Yes | userId |
MessageFeedbackResponse messageFeedback(MessageFeedbackRequest messageFeedbackRequest);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| messageId | String | Yes | messageId |
| rating | Rating | Yes | rating |
| content | String | Yes | Message Feedback Specific Information |
MessageFeedbackResponse
| Parameter name | Type | Description |
|---|
| result | String | Fixed return success |
DifyPageResult<MessagesResponseVO> messages(MessagesRequest request);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| conversationId | String | Yes | Chat session number |
| firstId | String | No | First record id |
| limit | Integer | No | Number of records per page, default 20条 |
| Parameter name | Type | Description |
|---|
| id | String | Message ID |
| conversationId | String | Conversation ID |
| inputs | Map<String, Object> | User input parameters |
| query | String | User input/question content |
| messageFiles | List<MessageFile> | Message files |
| answer | String | Answer message content |
| createdAt | Long | Creation timestamp |
| feedback | Feedback | Feedback information |
MessageFile Structure:
| Parameter name | Type | Description |
|---|
| id | String | File ID |
| filename | String | File name |
| type | String | File type, e.g., "image" |
| url | String | Preview image URL |
| mimeType | String | File MIME type |
| size | Long | File size in bytes |
| transferMethod | String | Transfer method |
| belongsTo | String | File owner, "user" or "assistant" |
| uploadFileId | String | Upload file ID |
| agentThoughts | List<MessageFileAgentThought> | Agent thoughts (not empty only in Agent mode) |
MessageFileAgentThought Structure:
| Parameter name | Type | Description |
|---|
| id | String | agent_thought ID, each Agent iteration has a unique id |
| messageId | String | Message unique ID |
| position | Integer | agent_thought position in the message, e.g., position 1 for the first iteration |
| thought | String | Agent's thought content |
| observation | String | Tool call result |
| tool | String | List of tools used, separated by ; |
| toolInput | String | Tool input, JSON formatted string (object). E.g.: {"dalle3": {"prompt": "a cute cat"}} |
| createdAt | Long | Creation timestamp, e.g.: 1705395332 |
| messageFiles | List<String> | File IDs associated with the current agent_thought |
| conversationId | String | Conversation ID |
Feedback Structure:
| Parameter name | Type | Description |
|---|
| rating | String | like/dislike rating |
List<String> messagesSuggested(String messageId, String apiKey, String userId);
| Parameter name | Type | Required | Description |
|---|
| messageId | String | Yes | messageId |
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
Return to the list of suggested response texts
DifyPageResult<AppFeedbackResponse> feedbacks(AppFeedbackPageRequest request);
AppFeedbackPageRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| page | Integer | No | Page number, default 1 |
| limit | Integer | No | Records per page, default 20, range 1-100 |
AppFeedbackResponse
| Parameter name | Type | Description |
|---|
| id | String | Feedback id |
| appId | String | Application id |
| conversationId | String | Conversation id |
| messageId | String | Message id |
| rating | String | Rating (like/dislike) |
| content | String | Feedback content |
| fromSource | String | Source |
| fromEndUserId | String | End user id |
| fromAccountId | String | Account id |
| createdAt | LocalDateTime | Creation timestamp |
| updatedAt | LocalDateTime | Update timestamp |
DifyPageResult<ConversationVariableResponse> conversationVariables(ConversationVariableRequest request);
ConversationVariableRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| conversationId | String | Yes | Conversation id |
| variableName | String | No | Variable name, return all if not empty |
ConversationVariableResponse
| Parameter name | Type | Description |
|---|
| id | String | Variable id |
| name | String | Variable name |
| valueType | String | Value type (string/json) |
| value | String | Variable value |
| description | String | Description |
| createdAt | Long | Creation timestamp (timestamp) |
| updatedAt | Long | Update timestamp (timestamp) |
ConversationVariableResponse updateConversationVariable(UpdateConversationVariableRequest request);
UpdateConversationVariableRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| conversationId | String | Yes | Conversation id |
| variableId | String | Yes | Variable id |
| value | String | Yes | New variable value |
ConversationVariableResponse
| Parameter name | Type | Description |
|---|
| id | String | Variable id |
| name | String | Variable name |
| valueType | String | Value type (string/json) |
| value | String | Variable value |
| description | String | Description |
| createdAt | Long | Creation timestamp (timestamp) |
| updatedAt | Long | Update timestamp (timestamp) |
DifyPageResult<MessageConversationsResponse> conversations(MessageConversationsRequest request);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| lastId | String | No | Last record id |
| limit | Integer | No | Number of records per page, default 20 |
| sortBy | String | No | Sort field, default -updated_at |
MessageConversationsResponse
| Parameter name | Type | Description |
|---|
| id | String | Chat session number |
| name | String | Session name |
| inputs | Map<String,Object> | Input parameter |
| status | String | Session state |
| introduction | String | Opening remarks |
| createdAt | Long | Creating timestamps |
| updatedAt | Long | Updating timestamps |
void deleteConversation(String conversationId, String apiKey, String userId);
| Parameter name | Type | Required | Description |
|---|
| conversationId | String | Yes | Chat session number |
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
MessageConversationsResponse renameConversation(RenameConversationRequest renameConversationRequest);
| Parameter name | Type | Required | Description |
|---|
| conversationId | String | Yes | Chat session number |
| name | String | Yes | Session name |
| autoGenerate | String | No | Auto-generated title, default false |
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
MessageConversationsResponse
| Parameter name | Type | Description |
|---|
| id | String | Chat session number |
| name | String | Session name |
| inputs | Map<String,Object> | Input parameter |
| status | String | Session state |
| introduction | String | Opening remarks |
| createdAt | Long | Creating timestamps |
| updatedAt | Long | Updating timestamps |
ResponseEntity<byte[]> textToAudio(TextToAudioRequest request);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| text | String | Yes | Convert Text |
| messageId | String | No | messageId |
Returns an audio file stream
import java.io.IOException;
private void textToAudio(TextToAudioRequest request, HttpServletResponse response) {
try {
ResponseEntity<byte[]> responseEntity = difyChat.textToAudio(request);
String type = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
response.setContentType(type != null ? type : "audio/mpeg");
String contentDisposition = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION);
if (contentDisposition != null) {
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
} else {
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=audio.mp3");
}
if (responseEntity.getBody() != null) {
response.getOutputStream().write(responseEntity.getBody());
response.getOutputStream().flush();
}
} catch (Exception e) {
log.error("textToAudio error: {}", e.getMessage());
throw new RuntimeException("textToAudio error");
}
}
DifyTextVO audioToText(AudioToTextRequest request);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| file | MultipartFile | Yes | Audio file |
| Parameter name | Type | Description |
|---|
| text | String | Convert Text |
AppParametersResponseVO parameters(String apiKey);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
AppParametersResponseVO
| Parameter name | Type | Description |
|---|
| openingStatement | String | Opening statement |
| suggestedQuestions | List<String> | Opening recommended questions |
| suggestedQuestionsAfterAnswer | Enabled | Enable recommended questions after answer |
| speechToText | Enabled | Speech-to-text feature config |
| textToSpeech | TextToSpeech | Text-to-speech feature config |
| retrieverResource | Enabled | Reference and attribution config |
| annotationReply | Enabled | Annotation reply config |
| moreLikeThis | Enabled | More like this feature config |
| userInputForm | List<UserInputForm> | User input form config |
| sensitiveWordAvoidance | Enabled | Sensitive word avoidance config |
| fileUpload | FileUpload | File upload config |
| systemParameters | FileUploadConfig | System parameters config |
Enabled Object Structure:
| Parameter name | Type | Description |
|---|
| enabled | Boolean | Whether enabled |
TextToSpeech Object Structure:
| Parameter name | Type | Description |
|---|
| enabled | Boolean | Whether enabled |
| voice | String | Voice type |
FileUpload Object Structure:
| Parameter name | Type | Description |
|---|
| enabled | Boolean | Whether file upload is enabled |
| image | FileUploadImage | Image upload configuration |
| allowedFileTypes | List<String> | Allowed file types list |
| allowedFileExtensions | List<String> | Allowed file extensions list |
| allowedFileUploadMethods | List<String> | Allowed upload methods list |
| numberLimits | Integer | File count limit |
| fileUploadConfig | FileUploadConfig | Detailed upload configuration |
FileUploadImage Object Structure:
| Parameter name | Type | Description |
|---|
| enabled | Boolean | Whether image upload is enabled |
| numberLimits | Integer | Image count limit, default 3 |
| transferMethods | List<String> | Transfer methods: remote_url, local_file |
FileUploadConfig Object Structure:
| Parameter name | Type | Description |
|---|
| fileSizeLimit | Integer | File size limit (MB) |
| batchCountLimit | Integer | Batch upload count limit |
| imageFileSizeLimit | Integer | Image file size limit (MB) |
| videoFileSizeLimit | Integer | Video file size limit (MB) |
| audioFileSizeLimit | Integer | Audio file size limit (MB) |
| workflowFileUploadLimit | Integer | Workflow file upload limit |
UserInputForm Object Structure:
| Parameter name | Type | Description |
|---|
| textInput | TextInput | Text input control config |
| paragraph | Paragraph | Paragraph text input config |
| select | Select | Dropdown control config |
TextInput Object Structure:
| Parameter name | Type | Description |
|---|
| label | String | Control display label |
| variable | String | Control ID |
| required | Boolean | Whether required |
| maxLength | Integer | Maximum length limit |
| defaultValue | String | Default value |
Paragraph Object Structure: Inherits from TextInput, has the same field structure
Select Object Structure:
| Parameter name | Type | Description |
|---|
| label | String | Control display label |
| variable | String | Control ID |
| required | Boolean | Whether required |
| maxLength | Integer | Maximum length limit |
| defaultValue | String | Default value |
| type | String | Dropdown type |
| options | List<String> | Options list |
FileUploadResponse fileUpload(FileUploadRequest request);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| file | MultipartFile | Yes | File to upload |
FileUploadResponse
| Parameter name | Type | Description |
|---|
| id | String | File id |
| name | String | File name |
| size | Integer | File size (bytes) |
| extension | String | File extension |
| mimeType | String | File MIME type |
| createdBy | String | Creator |
| createdAt | Long | Creation timestamp |
AppInfoResponse info(String apiKey);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
AppInfoResponse
| Parameter name | Type | Description |
|---|
| name | String | Application name |
| description | String | Application description |
| tags | List<String> | Application tags list |
AppMetaResponse meta(String apiKey);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
AppMetaResponse
| Parameter name | Type | Description |
|---|
| toolIcons | Map<String, Object> | Tool icons mapping |
AppSiteResponse site(String apikey);
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
AppSiteResponse
| Parameter name | Type | Description |
|---|
| title | String | WebApp name |
| chatColorTheme | String | Chat color theme, in hex format |
| chatColorThemeInverted | Boolean | Whether the chat color theme is inverted |
| iconType | IconTypeEnum | Icon type, emoji - emoji, image - picture |
| icon | String | Icon. If it's emoji type, it's an emoji symbol; if it's image type, it's an image URL |
| iconBackground | String | Background color in hex format |
| iconUrl | String | Icon URL |
| description | String | Description |
| copyright | String | Copyright information |
| privacyPolicy | String | Privacy policy link |
| customDisclaimer | String | Custom disclaimer |
| defaultLanguage | String | Default language |
| showWorkflowSteps | Boolean | Whether to show workflow details |
| useIconAsAnswerIcon | Boolean | Whether to replace 🤖 in chat with the WebApp icon |
ResponseEntity<byte[]> filePreview(FilePreviewRequest request);
FilePreviewRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | userId |
| fileId | String | Yes | Unique identifier of the file to preview, obtained from file upload API response |
| asAttachment | Boolean | No | Whether to force the file to be downloaded as an attachment. Default is false (preview in browser) |
Returns file content with appropriate headers for browser display or download.
- Content-Type: Set according to file MIME type
- Content-Length: File size in bytes (if available)
- Content-Disposition: Set to "attachment" if asAttachment=true
- Cache-Control: Cache headers for performance
- Accept-Ranges: Set to "bytes" for audio/video files
FilePreviewRequest request = new FilePreviewRequest("file-id-123")
.setApiKey("your-api-key")
.setUserId("user-123");
ResponseEntity<byte[]> response = difyChat.filePreview(request);
byte[] fileContent = response.getBody();
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
private void previewFile(String fileId, HttpServletResponse response) {
try {
FilePreviewRequest request = new FilePreviewRequest(fileId)
.setApiKey("your-api-key")
.setUserId("user-123")
.setAsAttachment(false);
ResponseEntity<byte[]> responseEntity = difyChat.filePreview(request);
String contentType = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
response.setContentType(contentType != null ? contentType : "application/octet-stream");
String contentLength = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_LENGTH);
if (contentLength != null) {
response.setContentLength(Integer.parseInt(contentLength));
}
String cacheControl = responseEntity.getHeaders().getFirst(HttpHeaders.CACHE_CONTROL);
if (cacheControl != null) {
response.setHeader(HttpHeaders.CACHE_CONTROL, cacheControl);
}
if (responseEntity.getBody() != null) {
response.getOutputStream().write(responseEntity.getBody());
response.getOutputStream().flush();
}
} catch (Exception e) {
log.error("File preview error: {}", e.getMessage());
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
private void downloadFile(String fileId, String filename, HttpServletResponse response) {
try {
FilePreviewRequest request = new FilePreviewRequest(fileId, true, "your-api-key", "user-123");
ResponseEntity<byte[]> responseEntity = difyChat.filePreview(request);
String contentType = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
response.setContentType(contentType != null ? contentType : "application/octet-stream");
String contentDisposition = responseEntity.getHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION);
if (contentDisposition != null) {
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
} else {
String safeFilename = filename != null ? filename : "download";
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + safeFilename + "\"");
}
if (responseEntity.getBody() != null) {
response.getOutputStream().write(responseEntity.getBody());
response.getOutputStream().flush();
}
} catch (Exception e) {
log.error("File download error: {}", e.getMessage());
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
required Dify version 1.2.0 or higher
DifyPageResult<AppAnnotationResponse> pageAppAnnotation(AppAnnotationPageRequest request);
AppAnnotationPageRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| page | Integer | No | Page number, default 1 |
| limit | Integer | No | Records per page, default 20, range 1-100 |
AppAnnotationResponse
| Parameter name | Type | Description |
|---|
| id | String | Annotation id |
| question | String | Question content |
| answer | String | Answer content |
| hitCount | Integer | Hit count |
| createdAt | Long | Creation timestamp |
AppAnnotationResponse createAppAnnotation(AppAnnotationCreateRequest request);
AppAnnotationCreateRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| question | String | Yes | Question content |
| answer | String | Yes | Answer content |
AppAnnotationResponse
| Parameter name | Type | Description |
|---|
| id | String | Annotation id |
| question | String | Question content |
| answer | String | Answer content |
| hitCount | Integer | Hit count |
| createdAt | Long | Creation timestamp |
required Dify version 1.3.1 or higher
AppAnnotationResponse updateAppAnnotation(AppAnnotationUpdateRequest request);
AppAnnotationUpdateRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | apiKey |
| userId | String | Yes | User id |
| annotationId | String | Yes | Annotation id |
| question | String | Yes | Question content |
| answer | String | Yes | Answer content |
AppAnnotationResponse
| Parameter name | Type | Description |
|---|
| id | String | Annotation id |
| question | String | Question content |
| answer | String | Answer content |
| hitCount | Integer | Hit count |
| createdAt | Long | Creation timestamp |
void deleteAppAnnotation(String annotationId, String apiKey);
| Parameter name | Type | Required | Description |
|---|
| annotationId | String | Yes | Annotation id |
| apiKey | String | Yes | apiKey |
not have
AppAnnotationReplyResponse annotationReply(AppAnnotationReplyRequest request);
AppAnnotationReplyRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | API key |
| userId | String | Yes | User ID |
| action | AnnotationReplyActionEnum | Yes | Reply action type |
| embeddingProviderName | String | No | Embedding model provider |
| embeddingModelName | String | No | Embedding model name |
| scoreThreshold | Float | No | Score threshold |
AnnotationReplyActionEnum values:
- enable - Enable annotation reply
- disable - Disable annotation reply
AppAnnotationReplyResponse
| Parameter name | Type | Description |
|---|
| jobId | String | Job ID |
| jobStatus | String | Job status |
| errorMsg | String | Error message |
AppAnnotationReplyResponse queryAnnotationReply(AppAnnotationReplyQueryRequest request);
AppAnnotationReplyQueryRequest
| Parameter name | Type | Required | Description |
|---|
| apiKey | String | Yes | API key |
| userId | String | Yes | User ID |
| action | AnnotationReplyActionEnum | Yes | Reply action type |
| jobId | String | Yes | Job ID to query |
AppAnnotationReplyResponse
| Parameter name | Type | Description |
|---|
| jobId | String | Job ID |
| jobStatus | String | Job status |
| errorMsg | String | Error message |