首页
/ Dify /openapi/v1 用户域 OpenAPI 深度指南:Bearer 鉴权、端点全解与源码实现剖析

Dify /openapi/v1 用户域 OpenAPI 深度指南:Bearer 鉴权、端点全解与源码实现剖析

2026-09-06 14:53:45作者:乔或婵

本文以 Dify 仓库中 openapi-openapi.md 这份 /openapi/v1 面的完整接口规范为骨架,逐组讲解其用户域(user-scoped)操作端点、请求/响应契约与鉴权模型,并结合 api/controllers/openapi/ 下的控制器源码说明版本门禁、分页封装、字段裁剪等关键机制的实现原理。读完本篇后,你可以用 Bearer Token 完整驱动 Dify 的应用运行、DSL 导入导出、工作区与成员管理、会话吊销以及 OAuth 设备授权流程,并能定位每个契约在源码中的定义位置。

1. OpenAPI 面是什么:定位、前缀与版本

Dify 后端暴露了多个 API 面(console、service、web、inner 等),其中 /openapi/v1 是面向用户域程序化访问的独立面:所有操作都以“某个账号(或 SSO 外部身份)”为主体,使用 Bearer Token 鉴权,主要服务于 difyctl CLI 与程序化客户端。规范文档明确其版本为 1.0,授权方式为:

  • Bearer(HTTP, bearer):将 Service API key 作为 Bearer token 放入 Authorization 头,格式为 Bearer API_KEY

这一面在 api/controllers/openapi/init.py 中注册,源码与规范文档一一对应:

bp = Blueprint("openapi", __name__, url_prefix="/openapi/v1")
attach_anti_framing(bp)
attach_version_gate(bp)

api = ExternalApi(
    bp,
    version="1.0",
    title="OpenAPI",
    description="User-scoped programmatic API (bearer auth)",
    error_body_formatter=OpenApiErrorFormatter(),
)

openapi_ns = Namespace("openapi", description="User-scoped operations", path="/")

几个值得注意的工程细节(均有源码依据):

  • api 并非普通 flask_restx Api,而是 libs/external_api.py 中的 ExternalApi,并挂接了统一的错误体格式化器 OpenApiErrorFormatter(定义于 api/controllers/openapi/_errors.py),这正是所有端点 default: Error 统一返回 ErrorBody 的来源。
  • attach_anti_framing(bp) 来自 libs/device_flow_security.py,为整个蓝图添加防嵌套框架(anti-framing)安全响应头。
  • attach_version_gate(bp) 是客户端版本门禁,见下文第 2.2 节。
  • api/controllers/openapi/init.py 中先集中 register_schema_models / register_response_schema_models / register_enum_models 注册全部请求、响应与枚举模型,再导入各控制器模块,保证 @returns / @accepts 装饰器能解析模型名——这与规范文档末尾 "Schemas" 一节列出的模型清单完全同源。

2. 元端点与版本门禁:/_health/_version

2.1 免鉴权探针

规范中列出的前两个端点不需要 Bearer 认证,实现见 api/controllers/openapi/index.py

端点 说明 200 响应
GET /_health 存活检查 HealthResponse{ "ok": true }
GET /_version 服务器版本 ServerVersionResponseversion(字符串)+ editionDeploymentEdition 枚举)

源码中 ServerVersionResponse 直接取 dify_config.project.versiondify_config.DEPLOYMENT_EDITION 两个配置值。HealthResponse 的模型注释写明 "no auth required",与文档中这两个端点只声明 200/default 的响应表一致。

2.2 客户端版本门禁(426 Upgrade Required)

/openapi/v1 面与 difyctl CLI 同步演进。api/controllers/openapi/_version_gate.py 实现了一个应用级请求钩子:

  • 仅拦截 User-Agent 匹配 difyctl/<semver> 的请求(正则见 _version_gate.py);
  • dify_config.tool.dify.min_difyctl_version 比较,只比较 major.minor.patch 数值核(避免 0.2.0-rc.1 这类预发布版本被误判低于 0.2.0 下限);
  • 版本过低的客户端收到 426,响应体是标准 ErrorBodycodeUPGRADE_REQUIREDhint 指向 difyctl 升级说明(docs.dify.ai 的 CLI 安装文档);
  • 白名单路径 /openapi/v1/_version/openapi/v1/_health 永远放行,保证过旧客户端仍能"发现自己过旧";
  • 钩子注册在 before_app_request 而非蓝图级 before_request,因此即使用户过旧客户端调用已删除的路径(本应 404),也会先收到 426 升级提示;
  • 对非 difyctl 或无法解析的 User-Agent 采用"失败放行"策略,只有可确认过旧时才拦截。

这对集成方的实际含义:调用该面时建议带上规范化的 User-Agent(difyctl/x.y.z (<os>; <arch>; <channel>)),以便在服务端升级破坏性路径时获得明确的 426 而非裸 404。

3. 账户与会话管理:/account/account/sessions

方法 路径 说明 关键响应
GET /account 当前账户信息 AccountResponse
GET /account/sessions 会话列表(查询参数 limit 默认 100、page 默认 1) 200 SessionListResponse;422 校验错误
DELETE /account/sessions/self 吊销当前会话 200 RevokeResponse{ "status": ... }
DELETE /account/sessions/{session_id} 吊销指定会话 200 RevokeResponse

相关契约(对应文档 Schemas 节):

  • AccountResponsesubject_type(必填)、subject_emailsubject_issueraccountAccountPayloadid / email / name 均必填)、default_workspace_idworkspacesWorkspacePayload[],每项含 id / name / role)。
  • SessionRowidclient_iddevice_labelprefix 必填;created_atexpires_atlast_used_at 可选——即每个设备授权会话都携带设备标签与 token 前缀,便于管理员识别"哪个设备、哪条 token"。
  • 会话列表分页查询模型 SessionListQuery 标注 "Strict (extra='forbid')",即传入未定义参数会直接 422,这是该面分页契约的统一风格(MemberListQueryPermittedExternalAppsListQuery 同理)。

4. 工作区:列表、切换、成员管理

方法 路径 说明 响应
GET /workspaces 工作区列表 200 WorkspaceListResponseworkspaces: WorkspaceSummaryResponse[]
GET /workspaces/{workspace_id} 工作区详情 200 WorkspaceDetailResponse
POST /workspaces/{workspace_id}:switch 切换当前工作区 200 WorkspaceDetailResponse
GET /workspaces/{workspace_id}/members 成员列表(limit 默认 20、page 默认 1) 200 MemberListResponse;422 校验错误
POST /workspaces/{workspace_id}/members 邀请成员 201 MemberInviteResponse;422 校验错误
DELETE /workspaces/{workspace_id}/members/{member_id} 移除成员 200 MemberActionResponseresult(默认 "success"
PATCH /workspaces/{workspace_id}/members/{member_id} 更新成员角色 200 MemberActionResponse;422 校验错误

字段契约要点:

  • WorkspaceSummaryResponseidnamerolestatuscurrent 均必填;WorkspaceDetailResponse 额外带 created_at
  • MemberInvitePayloademail 必填,role 为闭枚举 "admin" | "normal"
  • MemberRoleUpdatePayloadrole 同上闭枚举。
  • MemberInviteResponseemailinvite_urlmember_idroletenant_id 必填,result 默认 "success"——响应中的 invite_url 使 CLI/脚本能直接把邀请链接交付给被邀请人。
  • MemberResponseemailidnamerolestatus 必填,avatar 可选。

注意端点命名风格:动作型端点采用 :switch:confirm 这类 RFC 风格后缀而非把动作塞进 REST 资源层级,这在下面的 run/stop/submit/confirm 端点上一以贯之。

5. 应用列表与详情:/apps/apps/{app_id}

5.1 GET /apps 列表

查询参数:

参数 位置 必填 说明
workspace_id query 目标工作区,uuid
mode query 闭枚举 advanced-chat / agent-chat / chat / completion / workflow
name query 名称过滤(也接受 UUID)
page / limit query 默认 1 / 20

响应 AppListResponse 为分页信封:dataAppListRow[],必填)、pagelimittotalhas_more(均必填)。每行 AppListRowidnamemodeAppMode 枚举)、updated_atdescriptionworkspace_idworkspace_name

源码侧有三个值得展开的机制(api/controllers/openapi/apps.py):

  1. 可列应用类型的单一来源mode 过滤枚举并非随意定义:api/controllers/openapi/_models.pySupportedAppTypeAppMode精选子集,显式排除了仅运行时存在、并非独立应用的模式标签(rag-pipeline 是知识 Pipeline,channel 未使用)以及由 roster 面承接的 agent 类型。每个成员通过 AppMode.*.value 引用父枚举,形成"删减 AppMode 会在导入期报错"的编译期约束。参数、过滤与生成的 CLI 白名单全部派生自这一定义。
  2. RBAC 可见性下推。当 dify_config.RBAC_ENABLED 开启且调用者为账号时,AppAccessFilter 会把可访问应用 ID 集合下推进 SQL 查询参数(apps.py),保证 pagination.total 在各页之间一致——不可见行从不计入总数。终端用户(end user)不走此过滤,其访问由上游 scope 控制。
  3. UUID 快速路径name 若可解析为 UUID,直接走 get_visible_app_by_id 单查并校验 tenant_idworkspace_id 一致,返回 total=1 的单行分页,避免全量分页。

5.2 GET /apps/{app_id} 详情与 ?fields= 裁剪

路径参数 app_id 支持 UUID;?fields= 是响应块 allow-list,允许值见 apps.pyinfoparametersinput_schema。语义(对应 AppDescribeQuery 模型注释):

  • 省略或为空 → 返回全部块;
  • 传入未知成员 → ValidationError → 422。

响应 AppDescribeResponse 由三个可选块组成:

  • infoAppDescribeInfo):idnamemode 必填,另含 updated_atdescriptionservice_api_enabled(是否启用 Service API)、is_agentagent-chat / advanced-chat 为 true)。
  • parameters:与 service_api 面的应用参数端点同构,包含 opening_statementsuggested_questionsuser_input_formfile_uploadsystem_parameters 等键;应用不可用时回退为空结构。
  • input_schema:JSON Schema 风格的应用输入 schema,供客户端/LLM 在运行前校验输入。

app_id名称而非 UUID 时(列表端点的 name 参数语义在详情端点同样适用),_load() 要求必须同时给出 workspace_id 做按名查找;命中多个同名应用时返回 409,并在 message 中以表格列出所有候选 ID/MODE/NAME,提示"改用 UUID 重试"(apps.py)。

6. 应用运行、文件与任务:run / files / events / stop

方法 路径 说明 响应
POST /apps/{app_id}:run 运行应用,请求体 AppRunRequest 200 EventStreamResponse(SSE 流);422 校验错误
POST /apps/{app_id}/files 上传运行输入用的文件(multipart) 201 FileResponse;400(无文件/多文件/非法名/扩展名被禁);401(token 无效或过期);413(过大);415(类型不支持)
GET /apps/{app_id}/tasks/{task_id}/events 重连/订阅任务事件流 200 SSE 流
POST /apps/{app_id}/tasks/{task_id}:stop 停止任务 200 TaskStopResponse{ "result": "success" }

AppRunRequest 字段(全部可选,除 inputs):

字段 类型 说明
inputs object 必填,应用输入
query string 对话查询
conversation_id string 续接既有会话
files object[] 文件变量(通常引用 /files 上传后的 upload_file_id
auto_generate_name boolean 默认 true,自动生成会话名
workflow_id string 针对指定 workflow 版本
workspace_id string 工作区限定

文件上传是 run 流程的配套能力("上传文件以作为运行应用时的输入变量")。响应 FileResponse 关键字段:id(uuid,必填)、name(必填)、size(必填)、extensionmime_typepreview_urloriginal_urlcreated_atcreated_by 等;201 后拿到的文件句柄即可填入 AppRunRequest.files。错误码细分(400/401/413/415)在规范中逐一写明,方便脚本侧精确分支处理。

任务停止端点的 TaskStopResponse 契约在文档中被特别注明:handler 恒定返回 {"result": "success"},因此 result必填字段且无默认值,生成的客户端契约将其类型化为必填的 'success',而非可选字段——这是"契约即断言"的写法。

事件流EventStreamResponse)的模型注释表明它是 SSE 文本流;GET .../tasks/{task_id}/events 的两个查询参数:

  • continue_on_pause(boolean):暂停时是否保持事件流打开;
  • include_state_snapshot(boolean):是否包含 workflow 状态快照。

实现位于 api/controllers/openapi/app_run.pyapi/controllers/openapi/workflow_events.py

7. DSL 导出与导入:/apps/{app_id}/dsl/apps/{app_id}/dependencies:check/workspaces/{workspace_id}/apps/imports

7.1 导出

GET /apps/{app_id}/dsl,查询参数(AppDslExportQuery):

参数 类型 说明
include_secret boolean 在导出的 DSL 中包含加密后的密文值
workflow_id string (uuid) 导出指定 workflow 版本而非当前草稿

响应 AppDslExportResponse 仅一个必填字段:data(DSL YAML 字符串)。

7.2 依赖体检

GET /apps/{app_id}/dependencies:check 返回 CheckDependenciesResultleaked_dependenciesPluginDependency[],可选)。PluginDependencytypePluginDependencyType 枚举,valueGithub / Marketplace / Package 三态之一:

  • Githubgithub_plugin_unique_identifierpackagerepoversion 均必填;
  • Marketplacemarketplace_plugin_unique_identifier 必填,version 可选;
  • Packageplugin_unique_identifier 必填,version 可选。

这使导入前能程序化发现"引用了目标环境不可安装插件"的泄漏依赖。

7.3 导入(两阶段确认)

POST /workspaces/{workspace_id}/apps/imports,请求体 AppDslImportPayload

字段 必填 说明
mode "yaml-content""yaml-url"
yaml_content 条件必填 mode 为 yaml-content 时必填的 YAML DSL 字符串
yaml_url 条件必填 mode 为 yaml-url 时要抓取 YAML 的远程 URL
name / description 覆盖 DSL 中的应用名/描述
icon / icon_type / icon_background 图标覆盖
app_id 覆盖已有应用(仅 workflow/advanced-chat)

响应为 Import(来自 services/app_dsl_service.pyImport 实体,与 init.py 的注册一致):

字段 类型/必填 说明
id string,必填 导入任务 ID
status ImportStatus 枚举,必填 导入状态机
app_id / app_mode 可选 已落地的应用
current_dsl_version 默认 0.7.0 目标端 DSL 版本
imported_dsl_version 可选 源 DSL 版本
permission_keys string[],可选 需要的权限键
warnings DslImportWarning[],可选 未能在目标工作区恢复的可移植引用(codemessagepath 必填,details 可选)
error 可选 失败原因

HTTP 状态三态:200(导入完成)、202(待确认)、400(导入失败),加上 422 校验错误。

POST /workspaces/{workspace_id}/apps/imports/{import_id}:confirm 完成第二阶段确认:200(已确认)/ 400(失败)均返回 Import,供客户端轮询至终态。两阶段设计意味着跨环境迁移在确认前不产生副作用。

8. Human Input 表单:暂停点的人机交互回传

方法 路径 响应
GET /apps/{app_id}/human-input-forms/{form_token} 200 HumanInputFormDefinitionResponse
POST /apps/{app_id}/human-input-forms/{form_token}:submit 200 FormSubmitResponse(精确的空对象 {});422 校验错误
  • 定义响应form_content(必填,表单定义字符串)、resolved_default_values(必填,已解析的默认值对象)、inputsuser_actions(可选数组)、expiration_time(可选,秒级过期)。
  • 提交载荷 HumanInputFormSubmitPayload
    • action(必填):收件人点选的按钮 ID,必须匹配定义中 user_actions 的某个 id
    • inputs(必填):以输出变量名为键的人机输入值。段落/下拉取值用字符串;文件输入用文件映射,文件列表输入用文件映射列表。本地文件映射用 transfer_method=local_file + upload_file_id;远程文件映射用 transfer_method=remote_url + urlremote_url
  • FormSubmitResponse 的模型注释写明 extra='forbid'additionalProperties 钉死为 false,生成的契约是精确的 {} 而非欠标注的开放对象。

实现见 api/controllers/openapi/human_input_form.py。该组端点让外部系统(如邮件、IM 机器人)成为 workflow human-input 节点的"收件人",用 form_token 定位具体挂起实例。

9. OAuth 设备授权流程:/oauth/device/*

规范包含完整的设备授权(device authorization)面,五端点闭环:

方法 路径 请求体 / 参数 响应
POST /oauth/device/code DeviceCodeRequestclient_iddevice_label(均必填) DeviceCodeResponsedevice_codeuser_codeverification_uriexpires_ininterval(均必填)
GET /oauth/device/lookup 必填 query user_code DeviceLookupResponsevalid(必填)、client_idexpires_in_remaining
POST /oauth/device/approve DeviceMutateRequestuser_code(必填) DeviceMutateResponsestatus(必填)
POST /oauth/device/deny 同上 同上
POST /oauth/device/token DevicePollRequestclient_iddevice_code(均必填) DeviceTokenResponse(见下)

DeviceTokenResponse 是流程终点载荷:tokentoken_idexpires_atsubject_type(闭枚举 "account" | "external_sso",必填)均必填;另含 accountAccountPayload)、default_workspace_idsubject_emailsubject_issuerworkspacesWorkspacePayload[])等可选字段。subject_type 区分本机账号与外部 SSO 主体,设备授权因此同时覆盖两类身份。

流程语义:无头设备先申请 user_code/verification_uri(响应给出轮询 intervalexpires_in)→ 用户在浏览器 lookup 验证 code 有效性后 approve/deny → 设备端按 interval 轮询 /oauth/device/token 直至拿到 Bearer token。配套安全设施包括 libs/device_flow_security.py 的防 framing 头(第 1 节的 attach_anti_framing)以及 api/controllers/openapi/oauth_device.pyapi/controllers/openapi/oauth_device_sso.py 两个控制器分别承接 account 与 SSO 路径。

10. 允许对外暴露的应用:/permitted-external-apps

方法 路径 说明
GET /permitted-external-apps 列出当前用户允许对外访问的应用
GET /permitted-external-apps/{app_id} 单个应用详情

列表查询参数与 /apps 几乎同构(limit 默认 20、page 默认 1、mode 同为 SupportedAppType 闭枚举、name 名称过滤),但不需要 workspace_id(它按调用者权限域解析,且查询模型是 strict 的 PermittedExternalAppsListQuery)。响应 PermittedExternalAppsListResponseAppListResponse 同构(data/page/limit/total/has_more),详情端点复用 AppDescribeResponse?fields= 语义。实现位于 api/controllers/openapi/apps_permitted_external.py

11. 统一错误契约与分页信封

11.1 ErrorBody

规范中每个端点的 default 行都指向同一个规范错误体("Canonical non-2xx body"):

字段 类型 必填 说明
code string 错误码。线上类型是开放 string 而非枚举——生成的客户端 schema 保持开放枚举,服务端未来新增 code 时旧 CLI 仍可解析;枚举 OpenApiErrorCode 仅用于合约代码生成,格式化器测试将其发出的值钉死在枚举上
message string 人类可读消息
status integer HTTP 状态码
details ErrorDetail[] 校验细节,每项 type/msg 必填,loc 为 string/integer 混合数组(Pydantic 风格定位)
hint string 行动建议(如 426 的升级提示)

422 在校验失败时显式出现在端点表中,其 details 即为 Pydantic 校验错误的 loc/type/msg 三元组。

11.2 分页信封与 limit 上限

所有列表端点共用同一分页信封(PaginationEnvelopeapi/controllers/openapi/_models.py):page / limit / total / has_more / data 五字段,has_more = page * limit < totalbuild() 统一计算,杜绝各端点口径漂移。同时该文件定义了服务端 limit 硬上限 MAX_PAGE_LIMIT = 200,即列表端点查询参数中 limit 的实际取值上限——文档默认值(100/20)之外,脚本在拉大单页时以 200 为界。

12. 关键 Schema 索引(对照文档 Schemas 节)

下表汇总文档 Schemas 节中高频出现的核心契约及其源码出处,便于按图索骥:

Schema 用途 源码位置
AccountResponse / AccountPayload / WorkspacePayload 账户与所属工作区投影 api/controllers/openapi/_models.py
SessionRow / SessionListResponse 设备会话 同上
AppListQuery / AppListRow / AppListResponse 应用列表 同上 + apps.py
AppDescribeQuery / AppDescribeResponse 应用详情与 ?fields= 同上
AppRunRequest / EventStreamResponse 运行与 SSE app_run.pyEventStreamResponse 定义于 api/controllers/common/fields.py
FileResponse 文件上传 api/fields/file_fields.py
AppDslExportQuery / AppDslExportResponse / AppDslImportPayload / Import / DslImportWarning / CheckDependenciesResult / PluginDependency DSL 导入导出 app_dsl.pyImport 来自 services/app_dsl_service.pyCheckDependenciesResult 来自 services/entities/dsl_entities.py
HumanInputFormDefinitionResponse / HumanInputFormSubmitPayload / FormSubmitResponse human-input 表单 human_input_form.py
DeviceCode* / DeviceLookup* / DeviceMutate* / DevicePollRequest / DeviceTokenResponse 设备授权 oauth_device.pyoauth_device_sso.py
ErrorBody / ErrorDetail / OpenApiErrorCode 统一错误 api/controllers/openapi/_errors.py
HealthResponse / ServerVersionResponse / DeploymentEdition 元探针 index.py
TaskStopResponse / SimpleResultResponse 动作型 200 响应 init.py 引入
MemberInvitePayload / MemberResponse / MemberListResponse 工作区成员 workspaces.py

鉴权链路本身由 api/controllers/openapi/auth/ 下的组合器实现:auth_router.guard(scope=..., allowed_token_types=..., rbac=...) 装饰器在控制器入口统一完成 Bearer 校验、scope 检查与 RBAC 判定(例如应用详情端点要求 Scope.APPS_READ + TokenType.OAUTH_ACCOUNT + 应用查看布局 RBAC 权限),AuthData / CallerKind / RBACRequirement 等类型定义在 auth/data.py

13. 规范文档的生成与维护

仓库中该 Markdown 规范由开发工具链生成:api/dev/generate_swagger_markdown_docs.py 将各 API 面的 swagger 模型渲染为 api/openapi/markdown/ 下的四个面文档(console / service / web / openapi)。这意味着:

  • 端点参数、枚举取值、默认值等契约细节随控制器装饰器(@accepts / @returns)与 Pydantic 模型演进自动同步;
  • 本地校验响应契约的入口是 scripts/lint_controller_sqlalchemy.py 等仓库脚本与 api/tests/ 下的单测;
  • 阅读该面最新契约时,以仓库内这份 Markdown 与 api/controllers/openapi/ 源码为准即可,无需依赖外部文档站。

14. 快速上手:一条最小调用链

以 curl 形式串起前文能力(<API_KEY> 为 Bearer 凭据,<WS> 为目标工作区 ID):

# 0. 免鉴权探针
curl -s "$BASE/openapi/v1/_health"            # {"ok": true}
curl -s "$BASE/openapi/v1/_version"          # {"version": "...", "edition": "..."}

# 1. 确认身份与所属工作区
curl -s "$BASE/openapi/v1/account" -H "Authorization: Bearer <API_KEY>"
curl -s "$BASE/openapi/v1/workspaces" -H "Authorization: Bearer <API_KEY>"

# 2. 列出应用并查看详情(含输入 schema,用于构造运行请求)
curl -s "$BASE/openapi/v1/apps?workspace_id=<WS>&mode=chat" \
     -H "Authorization: Bearer <API_KEY>"
curl -s "$BASE/openapi/v1/apps/<APP_ID>?fields=info,input_schema" \
     -H "Authorization: Bearer <API_KEY>"

# 3. 上传文件并运行应用(SSE 流)
curl -s -F "file=@report.pdf" "$BASE/openapi/v1/apps/<APP_ID>/files" \
     -H "Authorization: Bearer <API_KEY>"
curl -N -X POST "$BASE/openapi/v1/apps/<APP_ID>:run" \
     -H "Authorization: Bearer <API_KEY>" -H "Content-Type: application/json" \
     -d '{"inputs": {"file": [{"transfer_method": "local_file", "upload_file_id": "<FILE_ID>"}]}}'

# 4. 导出 DSL / 导入到其他工作区(两阶段确认)
curl -s "$BASE/openapi/v1/apps/<APP_ID>/dsl" -H "Authorization: Bearer <API_KEY>"
curl -s -X POST "$BASE/openapi/v1/workspaces/<WS>/apps/imports" \
     -H "Authorization: Bearer <API_KEY>" -H "Content-Type: application/json" \
     -d '{"mode": "yaml-content", "yaml_content": "<DSL YAML>"}'

# 5. 清理:吊销当前会话
curl -s -X DELETE "$BASE/openapi/v1/account/sessions/self" \
     -H "Authorization: Bearer <API_KEY>"

错误处理约定:非 2xx 一律按 ErrorBody 解析,details 用于 422 字段级定位,hint 用于 426 升级提示;422 多由 strict 查询模型(extra='forbid')拒绝未知参数触发,排查时先核对参数拼写与所属端点。

15. 小结

/openapi/v1 是 Dify 面向程序化访问的用户域 API 面:版本 1.0、Bearer 鉴权、资源导向路径与 :action 动作端点混用、strict Pydantic 查询模型、统一 ErrorBody 与五字段分页信封、以及针对 difyctl 的 426 版本门禁。其端点覆盖了账户会话、工作区与成员、应用列表/详情/运行/文件、DSL 两阶段导入导出与依赖体检、human-input 表单回传、任务事件流与停止、设备授权登录以及外部可暴露应用清单。所有契约在 api/controllers/openapi/_models.pyapi/controllers/openapi/_errors.py 中集中定义,并通过 api/dev/generate_swagger_markdown_docs.py 同步为本文所依据的 openapi-openapi.md,实现"源码即契约、契约即文档"。

登录后查看全文
热门项目推荐
相关项目推荐