The Server API provides comprehensive functionality for interacting with the Dify platform, including managing applications, retrieving and initializing API keys for both applications and datasets. All interfaces require a valid API key for authentication. Use the DifyServer interface instance.
By default, if the current environment contains redis, then use redis to persist the token, if not, then use the default implementation to save the token (it will be lost if the service is restarted).
List<AppsResponseVO> apps(String mode, String name);
| Parameter name | Type | Required | Description |
|---|
| mode | String | No | mode chat\agent-chat\completion\advanced-chat\workflow |
| name | String | No | Application name, used to filter the application list (optional) |
AppsResponseVO
| Parameter name | Type | Description |
|---|
| id | String | Application ID |
| name | String | Application name |
| maxActiveRequests | Integer | Maximum active requests |
| description | String | Application description |
| mode | String | Application mode |
| iconType | String | Icon type |
| icon | String | Icon |
| iconBackground | String | Icon background |
| iconUrl | String | Icon URL |
| modelConfig | ModelConfig | Model configuration |
| workflow | Object | Workflow information |
| useIconAsAnswerIcon | Boolean | Whether to use icon as answer icon |
| createdBy | String | Creator ID |
| createdAt | Long | Creation time (timestamp) |
| updatedBy | String | Updater ID |
| updatedAt | Long | Update time (timestamp) |
| tags | List<String> | Application tags |
ModelConfig
| Parameter name | Type | Description |
|---|
| model | Model | Model information |
| prePrompt | String | Pre-prompt text |
| createdBy | String | Creator ID |
| createdAt | Long | Creation time (timestamp) |
| updatedBy | String | Updater ID |
| updatedAt | Long | Update time (timestamp) |
Model
| Parameter name | Type | Description |
|---|
| provider | String | Model provider |
| name | String | Model name |
| mode | String | Model mode |
| completionParams | CompletionParams | Completion parameters |
CompletionParams
| Parameter name | Type | Description |
|---|
| stop | List<String> | Stop sequences |
@Resource
private DifyServer difyServer;
@Test
public void testGetApps() {
List<AppsResponseVO> apps = difyServer.apps("");
List<AppsResponseVO> filteredApps = difyServer.apps("myApp");
}
AppsResponseResult apps(AppsRequest appsRequest);
AppsRequest
| Parameter name | Type | Required | Description |
|---|
| page | Integer | No | Page number (default: 1) |
| limit | Integer | No | Number of items per page (default: 20, range: 1-100) |
| mode | String | No | Application mode filter: chat\agent-chat\completion\advanced-chat\workflow |
| name | String | No | Application name filter |
| isCreatedByMe | Boolean | No | Whether the application is created by the current user |
AppsResponseResult
| Parameter name | Type | Description |
|---|
| data | List<AppsResponse> | Current page data list |
| hasMore | Boolean | Whether there are more pages |
| limit | Integer | Items per page |
| page | Integer | Current page number |
| total | Integer | Total number of items |
The structure of AppsResponse is the same as defined above in section 1.1.
@Resource
private DifyServer difyServer;
@Test
public void testGetAppsPaginated() {
AppsRequest request = new AppsRequest();
request.setPage(1);
request.setLimit(10);
request.setMode("chat");
request.setName("myApp");
request.setIsCreatedByMe(true);
AppsResponseResult result = difyServer.apps(request);
System.out.println("Current page: " + result.getPage());
System.out.println("Items per page: " + result.getLimit());
System.out.println("Total items: " + result.getTotal());
System.out.println("Has more: " + result.getHasMore());
System.out.println("Data size: " + result.getData().size());
}
AppsResponseVO app(String appId);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
Same as the AppsResponseVO structure defined above.
@Resource
private DifyServer difyServer;
@Test
public void testGetApp() {
AppsResponseVO app = difyServer.app("app-123456789");
}
List<ApiKeyResponseVO> getAppApiKey(String id);
| Parameter name | Type | Required | Description |
|---|
| id | String | Yes | Application ID |
ApiKeyResponseVO
| Parameter name | Type | Description |
|---|
| id | String | API Key ID |
| token | String | API Key token value |
@Resource
private DifyServer difyServer;
@Test
public void testGetAppApiKeys() {
List<ApiKeyResponseVO> apiKeys = difyServer.getAppApiKey("app-123456789");
}
List<ApiKeyResponseVO> initAppApiKey(String id);
| Parameter name | Type | Required | Description |
|---|
| id | String | Yes | Application ID |
Same as the ApiKeyResponseVO structure defined above.
@Resource
private DifyServer difyServer;
@Test
public void testInitAppApiKey() {
List<ApiKeyResponseVO> apiKeys = difyServer.initAppApiKey("app-123456789");
}
void deleteAppApiKey(String appId, String apiKeyId);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| apiKeyId | String | Yes | API Key ID |
This method does not return a value. It returns 204 No Content on success.
@Resource
private DifyServer difyServer;
@Test
public void testDeleteAppApiKey() {
difyServer.deleteAppApiKey("app-123456789", "key-789012345");
}
List<DatasetApiKeyResponseVO> getDatasetApiKey();
DatasetApiKeyResponseVO
| Parameter name | Type | Description |
|---|
| id | String | API Key ID |
| type | String | API Key type |
| token | String | API Key token value |
| lastUsedAt | Long | Last used time (timestamp) |
| createdAt | Long | Creation time (timestamp) |
@Resource
private DifyServer difyServer;
@Test
public void testGetDatasetApiKeys() {
List<DatasetApiKeyResponseVO> datasetApiKeys = difyServer.getDatasetApiKey();
}
List<DatasetApiKeyResponseVO> initDatasetApiKey();
Same as the DatasetApiKeyResponseVO structure defined above.
@Resource
private DifyServer difyServer;
@Test
public void testInitDatasetApiKey() {
List<DatasetApiKeyResponseVO> datasetApiKeys = difyServer.initDatasetApiKey();
}
void deleteDatasetApiKey(String apiKeyId);
| Parameter name | Type | Required | Description |
|---|
| apiKeyId | String | Yes | API Key ID |
This method does not return a value. It returns 204 No Content on success.
@Resource
private DifyServer difyServer;
@Test
public void testDeleteDatasetApiKey() {
difyServer.deleteDatasetApiKey("89f04b59-6906-4d32-a630-d2911d3b5fd8");
}
DocumentIndexingStatusResponse getDatasetIndexingStatus(String datasetId);
| Parameter name | Type | Required | Description |
|---|
| datasetId | String | Yes | Dataset ID |
DocumentIndexingStatusResponse
| Parameter name | Type | Description |
|---|
| data | List<ProcessingStatus> | Document indexing status list |
ProcessingStatus
| Parameter name | Type | Description |
|---|
| id | String | Document ID |
| indexingStatus | String | Indexing status: waiting, parsing, cleaning, splitting, indexing, completed, error, paused |
| processingStartedAt | Long | Processing start time (timestamp) |
| parsingCompletedAt | Long | Parsing completion time (timestamp) |
| cleaningCompletedAt | Long | Cleaning completion time (timestamp) |
| splittingCompletedAt | Long | Splitting completion time (timestamp) |
| completedAt | Long | Completion time (timestamp) |
| pausedAt | Long | Pause time (timestamp) |
| error | String | Error message |
| stoppedAt | Long | Stop time (timestamp) |
| completedSegments | Integer | Number of completed segments |
| totalSegments | Integer | Total number of segments |
@Resource
private DifyServer difyServer;
@Test
public void testGetDatasetIndexingStatus() {
String datasetId = "dataset-123456789";
DocumentIndexingStatusResponse indexingStatus = difyServer.getDatasetIndexingStatus(datasetId);
if (indexingStatus.getData() != null && !indexingStatus.getData().isEmpty()) {
for (DocumentIndexingStatusResponse.ProcessingStatus doc : indexingStatus.getData()) {
System.out.println("Document ID: " + doc.getId());
System.out.println("Indexing Status: " + doc.getIndexingStatus());
System.out.println("Completed Segments: " + doc.getCompletedSegments() + "/" + doc.getTotalSegments());
}
}
}
DocumentIndexingStatusResponse.ProcessingStatus getDocumentIndexingStatus(String datasetId, String documentId);
| Parameter name | Type | Required | Description |
|---|
| datasetId | String | Yes | Dataset ID |
| documentId | String | Yes | Document ID |
ProcessingStatus (same structure as defined in section 2.4)
@Resource
private DifyServer difyServer;
@Test
public void testGetDocumentIndexingStatus() {
String datasetId = "dataset-123456789";
String documentId = "doc-987654321";
DocumentIndexingStatusResponse.ProcessingStatus documentStatus =
difyServer.getDocumentIndexingStatus(datasetId, documentId);
System.out.println("Document ID: " + documentStatus.getId());
System.out.println("Indexing Status: " + documentStatus.getIndexingStatus());
System.out.println("Completed Segments: " + documentStatus.getCompletedSegments() + "/" + documentStatus.getTotalSegments());
if (documentStatus.getError() != null) {
System.out.println("Error Message: " + documentStatus.getError());
}
}
DatasetErrorDocumentsResponse getDatasetErrorDocuments(String datasetId);
| Parameter name | Type | Required | Description |
|---|
| datasetId | String | Yes | Dataset ID |
DatasetErrorDocumentsResponse
| Parameter name | Type | Description |
|---|
| data | List<ErrorDocument> | Error document list |
| total | Integer | Total number of errors |
ErrorDocument
| Parameter name | Type | Description |
|---|
| id | String | Document ID |
| name | String | Document name |
| error | String | Error message |
| indexingStatus | String | Indexing status (usually "error") |
| createdAt | Long | Creation time (timestamp) |
| updatedAt | Long | Update time (timestamp) |
@Resource
private DifyServer difyServer;
@Test
public void testGetDatasetErrorDocuments() {
String datasetId = "dataset-123456789";
DatasetErrorDocumentsResponse errorDocuments = difyServer.getDatasetErrorDocuments(datasetId);
System.out.println("Total Error Documents: " + errorDocuments.getTotal());
if (errorDocuments.getData() != null && !errorDocuments.getData().isEmpty()) {
for (DatasetErrorDocumentsResponse.ErrorDocument doc : errorDocuments.getData()) {
System.out.println("Document ID: " + doc.getId());
System.out.println("Document Name: " + doc.getName());
System.out.println("Error Message: " + doc.getError());
}
} else {
System.out.println("No error documents found");
}
}
void retryDocumentIndexing(DocumentRetryRequest request);
DocumentRetryRequest
| Parameter name | Type | Required | Description |
|---|
| datasetId | String | Yes | Dataset ID |
| documentIds | List<String> | Yes | List of document IDs to retry |
This method does not return a value. It returns 204 No Content on success.
@Resource
private DifyServer difyServer;
@Test
public void testRetryDocumentIndexing() {
String datasetId = "dataset-123456789";
DatasetErrorDocumentsResponse errorDocuments = difyServer.getDatasetErrorDocuments(datasetId);
if (errorDocuments.getData() != null && !errorDocuments.getData().isEmpty()) {
List<String> errorDocIds = errorDocuments.getData().stream()
.map(DatasetErrorDocumentsResponse.ErrorDocument::getId)
.collect(Collectors.toList());
DocumentRetryRequest request = new DocumentRetryRequest();
request.setDatasetId(datasetId);
request.setDocumentIds(errorDocIds);
difyServer.retryDocumentIndexing(request);
System.out.println("Triggered indexing retry for " + errorDocIds.size() + " documents");
} else {
System.out.println("No error documents to retry");
}
}
DifyPageResult<ChatConversationResponse> chatConversations(ChatConversationsRequest request);
ChatConversationsRequest
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| page | Integer | No | Page number (default: 1) |
| limit | Integer | No | Number of items per page (default: 10, range: 1-100) |
| start | String | No | Start time, format: yyyy-MM-dd HH:mm |
| end | String | No | End time, format: yyyy-MM-dd HH:mm |
| sortBy | String | No | Sort field, e.g., -created_at (sort by creation time descending) |
| annotationStatus | String | No | Annotation status: all, not_annotated, annotated |
DifyPageResult<ChatConversationResponse>
| Parameter name | Type | Description |
|---|
| data | List<ChatConversationResponse> | Current page data list |
| hasMore | Boolean | Whether there are more pages |
| limit | Integer | Items per page |
| page | Integer | Current page number |
| total | Integer | Total number of items |
ChatConversationResponse
| Parameter name | Type | Description |
|---|
| id | String | Conversation ID |
| status | String | Conversation status |
| fromSource | String | Source |
| fromEndUserId | String | End user ID |
| fromEndUserSessionId | String | End user session ID |
| fromAccountId | String | Account ID |
| fromAccountName | String | Account name |
| name | String | Conversation name |
| summary | String | Conversation summary |
| readAt | Long | Read time (timestamp) |
| createdAt | Long | Creation time (timestamp) |
| updatedAt | Long | Update time (timestamp) |
| annotated | Boolean | Whether annotated |
| modelConfig | Map<String, Object> | Model configuration |
| messageCount | Integer | Message count |
| userFeedbackStats | FeedbackStats | User feedback statistics |
| adminFeedbackStats | FeedbackStats | Admin feedback statistics |
| statusCount | StatusCount | Status count |
FeedbackStats
| Parameter name | Type | Description |
|---|
| like | Integer | Like count |
| dislike | Integer | Dislike count |
StatusCount
| Parameter name | Type | Description |
|---|
| success | Integer | Success count |
| failed | Integer | Failed count |
| partialSuccess | Integer | Partial success count |
@Resource
private DifyServer difyServer;
@Test
public void testGetChatConversations() {
ChatConversationsRequest request = new ChatConversationsRequest();
request.setAppId("app-123456789");
request.setPage(1);
request.setLimit(10);
request.setStart("2025-10-23 00:00");
request.setEnd("2025-10-30 23:59");
request.setAnnotationStatus("all");
request.setSortBy("-created_at");
DifyPageResult<ChatConversationResponse> result = difyServer.chatConversations(request);
System.out.println("Current page: " + result.getPage());
System.out.println("Items per page: " + result.getLimit());
System.out.println("Total items: " + result.getTotal());
System.out.println("Has more: " + result.getHasMore());
System.out.println("Data size: " + result.getData().size());
for (ChatConversationResponse conversation : result.getData()) {
System.out.println("Conversation ID: " + conversation.getId());
System.out.println("Conversation name: " + conversation.getName());
System.out.println("Is annotated: " + conversation.isAnnotated());
}
}
List<DailyConversationsResponse> dailyConversations(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
DailyConversationsResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| conversationCount | Integer | Number of conversations on that day |
@Resource
private DifyServer difyServer;
@Test
public void testGetDailyConversations() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<DailyConversationsResponse> dailyStats = difyServer.dailyConversations(appId, start, end);
if (dailyStats != null) {
for (DailyConversationsResponse dailyStat : dailyStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("Conversation count: " + dailyStat.getConversationCount());
}
}
}
List<DailyEndUsersResponse> dailyEndUsers(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
DailyEndUsersResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| terminalCount | Integer | Number of end users on that day |
@Resource
private DifyServer difyServer;
@Test
public void testGetDailyEndUsers() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<DailyEndUsersResponse> dailyEndUsersStats = difyServer.dailyEndUsers(appId, start, end);
if (dailyEndUsersStats != null) {
for (DailyEndUsersResponse dailyStat : dailyEndUsersStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("End users count: " + dailyStat.getTerminalCount());
}
}
}
List<AverageSessionInteractionsResponse> averageSessionInteractions(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
AverageSessionInteractionsResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| interactions | Double | Average number of interactions per session on that day |
@Resource
private DifyServer difyServer;
@Test
public void testGetAverageSessionInteractions() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<AverageSessionInteractionsResponse> averageSessionInteractionsStats = difyServer.averageSessionInteractions(appId, start, end);
if (averageSessionInteractionsStats != null) {
for (AverageSessionInteractionsResponse dailyStat : averageSessionInteractionsStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("Average interactions per session: " + dailyStat.getInteractions());
}
}
}
List<TokensPerSecondResponse> tokensPerSecond(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
TokensPerSecondResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| tps | Double | Tokens per second on that day |
@Resource
private DifyServer difyServer;
@Test
public void testGetTokensPerSecond() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<TokensPerSecondResponse> tokensPerSecondStats = difyServer.tokensPerSecond(appId, start, end);
if (tokensPerSecondStats != null) {
for (TokensPerSecondResponse dailyStat : tokensPerSecondStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("Tokens per second: " + dailyStat.getTps());
}
}
}
List<UserSatisfactionRateResponse> userSatisfactionRate(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
UserSatisfactionRateResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| rate | Double | User satisfaction rate on that day |
@Resource
private DifyServer difyServer;
@Test
public void testGetUserSatisfactionRate() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<UserSatisfactionRateResponse> userSatisfactionRateStats = difyServer.userSatisfactionRate(appId, start, end);
if (userSatisfactionRateStats != null) {
for (UserSatisfactionRateResponse dailyStat : userSatisfactionRateStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("User satisfaction rate: " + dailyStat.getRate());
}
}
}
List<TokenCostsResponse> tokenCosts(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
TokenCostsResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| token_count | Integer | Number of tokens on that day |
| total_price | String | Total price for that day |
| currency | String | Currency type |
@Resource
private DifyServer difyServer;
@Test
public void testGetTokenCosts() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<TokenCostsResponse> tokenCostsStats = difyServer.tokenCosts(appId, start, end);
if (tokenCostsStats != null) {
for (TokenCostsResponse dailyStat : tokenCostsStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("Token count: " + dailyStat.getTokenCount());
System.out.println("Total price: " + dailyStat.getTotalPrice());
System.out.println("Currency: " + dailyStat.getCurrency());
}
}
}
List<DailyMessagesResponse> dailyMessages(String appId, LocalDateTime start, LocalDateTime end);
| Parameter name | Type | Required | Description |
|---|
| appId | String | Yes | Application ID |
| start | LocalDateTime | Yes | Start time, format: yyyy-MM-dd HH:mm |
| end | LocalDateTime | Yes | End time, format: yyyy-MM-dd HH:mm |
DailyMessagesResponse
| Parameter name | Type | Description |
|---|
| date | String | Date, format: yyyy-MM-dd |
| message_count | Integer | Number of messages on that day |
@Resource
private DifyServer difyServer;
@Test
public void testGetDailyMessages() {
String appId = "08534c1a-4316-4cd3-806d-bbbca03f58aa";
LocalDateTime start = LocalDateTime.of(2025, 10, 23, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 10, 30, 23, 59);
List<DailyMessagesResponse> dailyMessagesStats = difyServer.dailyMessages(appId, start, end);
if (dailyMessagesStats != null) {
for (DailyMessagesResponse dailyStat : dailyMessagesStats) {
System.out.println("Date: " + dailyStat.getDate());
System.out.println("Message count: " + dailyStat.getMessageCount());
}
}
}