# Dify Workflow API 文档

## 概述

Workflow 应用无会话支持,适合用于翻译、文章写作、总结等 AI 场景。

**Base URL:** `http://192.168.2.236:3001/v1`

## 认证

所有 API 请求需在 HTTP Header 中包含 API-Key:

```
Authorization: Bearer {API_KEY}
```

## 1. 执行 Workflow

**接口:** `POST /workflows/run`

### 请求参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| inputs | object | ✓ | 允许传入 App 定义的各变量值。inputs 参数包含了多组键值对,每组的键对应一个特定变量,每组的值则是该变量的具体值 |
| response_mode | string | ✓ | 返回响应模式:`streaming`(流式,推荐)或`blocking`(阻塞,Cloudflare 限制 100 秒超时) |
| user | string | ✓ | 用户标识,用于定义终端用户的身份,方便检索、统计。需保证用户标识在应用内唯一 |

### 文件列表类型变量

| 字段 | 类型 | 说明 |
|------|------|------|
| type | string | 文件类型:document/image/audio/video/custom |
| transfer_method | string | 传递方式:remote_url(图片地址)或local_file(上传文件) |
| url | string | 图片地址(仅当传递方式为 remote_url 时) |
| upload_file_id | string | 上传文件 ID(仅当传递方式为 local_file 时) |

**支持的文件类型:**
- **document**: TXT, MD, PDF, HTML, XLSX, DOCX, CSV, PPTX, XML, EPUB
- **image**: JPG, PNG, GIF, WEBP, SVG
- **audio**: MP3, WAV, M4A, WEBM, AMR
- **video**: MP4, MOV, MPEG

### 响应格式

#### CompletionResponse(阻塞模式)

| 字段 | 类型 | 说明 |
|------|------|------|
| workflow_run_id | string | workflow 执行 ID |
| task_id | string | 任务 ID,用于请求跟踪和停止响应接口 |
| data.id | string | workflow 执行 ID |
| data.workflow_id | string | 关联 Workflow ID |
| data.status | string | 执行状态:running/succeeded/failed/stopped |
| data.outputs | json | 可选,输出内容 |
| data.error | string | 可选,错误原因 |
| data.elapsed_time | float | 可选,耗时(秒) |
| data.total_tokens | int | 可选,总使用 tokens |
| data.total_steps | int | 总步数,默认 0 |
| data.created_at | timestamp | 开始时间 |
| data.finished_at | timestamp | 结束时间 |

#### ChunkCompletionResponse(流式模式)

**事件类型:**

**1. workflow_started**

| 字段 | 类型 | 说明 |
|------|------|------|
| task_id | string | 任务 ID |
| workflow_run_id | string | workflow 执行 ID |
| event | string | 固定为 workflow_started |
| data.id | string | workflow 执行 ID |
| data.workflow_id | string | 关联 Workflow ID |
| data.sequence_number | int | 自增序号,从 1 开始 |
| data.created_at | timestamp | 开始时间 |

**2. node_started**

| 字段 | 类型 | 说明 |
|------|------|------|
| data.node_id | string | 节点 ID |
| data.node_type | string | 节点类型 |
| data.title | string | 节点名称 |
| data.index | int | 执行序号 |
| data.predecessor_node_id | string | 前置节点 ID |
| data.inputs | object | 节点中所有使用到的前置节点变量内容 |

**3. node_finished**

| 字段 | 类型 | 说明 |
|------|------|------|
| data.node_id | string | 节点 ID |
| data.status | string | 执行状态:running/succeeded/failed/stopped |
| data.outputs | json | 可选,输出内容 |
| data.error | string | 可选,错误原因 |
| data.elapsed_time | float | 可选,耗时(秒) |
| data.execution_metadata.total_tokens | int | 可选,总使用 tokens |
| data.execution_metadata.total_price | decimal | 可选,总费用 |
| data.execution_metadata.currency | string | 可选,货币(USD/RMB) |

**4. workflow_finished**

| 字段 | 类型 | 说明 |
|------|------|------|
| data.status | string | 执行状态:running/succeeded/failed/stopped |
| data.outputs | json | 可选,输出内容 |
| data.error | string | 可选,错误原因 |
| data.total_tokens | int | 可选,总使用 tokens |
| data.finished_at | timestamp | 结束时间 |

**5. tts_message** - TTS 音频流事件(Mp3 格式,base64 编码)

| 字段 | 类型 | 说明 |
|------|------|------|
| task_id | string | 任务 ID |
| message_id | string | 消息唯一 ID |
| audio | string | Base64 编码的音频内容 |
| created_at | int | 创建时间戳 |

**6. tts_message_end** - TTS 音频流结束

**7. ping** - 每 10 秒心跳保活

### 错误码

| 状态码 | 错误码 | 说明 |
|--------|--------|------|
| 400 | invalid_param | 传入参数异常 |
| 400 | app_unavailable | App 配置不可用 |
| 400 | provider_not_initialize | 无可用模型凭据配置 |
| 400 | provider_quota_exceeded | 模型调用额度不足 |
| 400 | workflow_request_error | workflow 执行失败 |
| 500 | - | 服务内部异常 |

---

## 2. 查询 Workflow 执行状态

**接口:** `GET /workflows/run/:workflow_run_id`

### 响应字段

| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | workflow 执行 ID |
| workflow_id | string | 关联的 Workflow ID |
| status | string | 执行状态:running/succeeded/failed/stopped |
| inputs | json | 任务输入内容 |
| outputs | json | 任务输出内容 |
| error | string | 错误原因 |
| total_steps | int | 任务执行总步数 |
| total_tokens | int | 任务执行总 tokens |
| created_at | timestamp | 任务开始时间 |
| finished_at | timestamp | 任务结束时间 |
| elapsed_time | float | 耗时(秒) |

---

## 3. 停止 Workflow 执行

**接口:** `POST /workflows/tasks/:task_id/stop`

### 请求参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| user | string | ✓ | 用户标识,必须和发送消息接口传入 user 保持一致 |

---

## 4. 上传文件

**接口:** `POST /files/upload`

### 请求参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| file | file | ✓ | 要上传的文件 |
| user | string | ✓ | 用户标识 |

### 响应字段

| 字段 | 类型 | 说明 |
|------|------|------|
| id | uuid | ID |
| name | string | 文件名 |
| size | int | 文件大小(byte) |
| extension | string | 文件后缀 |
| mime_type | string | 文件 mime-type |
| created_by | uuid | 上传人 ID |
| created_at | timestamp | 上传时间 |

### 错误码

| 状态码 | 错误码 | 说明 |
|--------|--------|------|
| 400 | no_file_uploaded | 必须提供文件 |
| 413 | file_too_large | 文件太大 |
| 415 | unsupported_file_type | 不支持的文件类型 |
| 503 | s3_connection_failed | 无法连接到 S3 服务 |

---

## 5. 获取 Workflow 日志

**接口:** `GET /workflows/logs`

### 查询参数

| 参数 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| keyword | string | 关键字 | - |
| status | string | 执行状态:succeeded/failed/stopped | - |
| page | int | 当前页码 | 1 |
| limit | int | 每页条数 | 20 |

### 响应字段

| 字段 | 类型 | 说明 |
|------|------|------|
| page | int | 当前页码 |
| limit | int | 每页条数 |
| total | int | 总条数 |
| has_more | bool | 是否还有更多数据 |
| data[].workflow_run.id | string | 标识 |
| data[].workflow_run.status | string | 执行状态 |
| data[].workflow_run.elapsed_time | float | 耗时(秒) |
| data[].workflow_run.total_tokens | int | 消耗的 token 数量 |

---

## 6. 获取应用信息

**接口:** `GET /info`

### 响应字段

| 字段 | 类型 | 说明 |
|------|------|------|
| name | string | 应用名称 |
| description | string | 应用描述 |
| tags | array[string] | 应用标签 |

---

## 7. 获取应用参数

**接口:** `GET /parameters`

### 响应字段

| 字段 | 类型 | 说明 |
|------|------|------|
| user_input_form[].text-input.label | string | 控件展示标签名 |
| user_input_form[].text-input.variable | string | 控件 ID |
| user_input_form[].text-input.required | bool | 是否必填 |
| user_input_form[].text-input.default | string | 默认值 |
| file_upload.image.enabled | bool | 是否开启 |
| file_upload.image.number_limits | int | 图片数量限制,默认 3 |
| file_upload.image.transfer_methods | array[string] | 传递方式:remote_url/local_file |
| system_parameters.file_size_limit | int | 文档上传大小限制(MB) |
| system_parameters.image_file_size_limit | int | 图片文件上传大小限制(MB) |
| system_parameters.audio_file_size_limit | int | 音频文件上传大小限制(MB) |
| system_parameters.video_file_size_limit | int | 视频文件上传大小限制(MB) |