--- sidebar_position: 7 title: API Contracts sidebar_label: API description: MindSpace HTTP resources, endpoints, validation, errors, pagination, and idempotency --- # API 与错误契约 ## 通用规则 - API 前缀:`/api/mindspace/v1`。 - JSON 使用 `snake_case` 或仓库既有规范,前后端统一。 - 时间使用 ISO 8601 UTC。 - 写请求携带 CSRF 防护或使用不依赖 cookie 的安全认证方案。 - 创建和高价值写操作支持 `Idempotency-Key`。 - 每个响应携带 `request_id`。 - 列表使用 cursor 分页,避免大列表 offset 漂移。 - 所有 ID 都视为不可信输入,并校验所有权。 ## 响应结构 成功: ```json { "data": {}, "request_id": "req_..." } ``` 列表: ```json { "data": [], "page": { "next_cursor": null, "has_more": false }, "request_id": "req_..." } ``` 错误: ```json { "error": { "code": "quota_exceeded", "message": "剩余空间不足", "details": { "required_bytes": 1024, "available_bytes": 512 } }, "request_id": "req_..." } ``` ## 错误码 | HTTP | code | 场景 | | --- | --- | --- | | 400 | validation_failed | 请求字段错误 | | 401 | authentication_required | 未登录或会话失效 | | 403 | permission_denied | 无操作权限 | | 404 | resource_not_found | 不存在或对当前用户不可见 | | 409 | slug_conflict | slug 已存在 | | 409 | version_conflict | 乐观锁冲突 | | 409 | invalid_state_transition | 状态不允许 | | 413 | file_too_large | 单文件超限 | | 415 | unsupported_file_type | 类型不支持 | | 422 | security_scan_required | 尚未扫描 | | 422 | security_risk_blocked | 风险阻断 | | 429 | quota_exceeded | 存储或套餐配额不足 | | 429 | rate_limited | 请求过快 | | 500 | internal_error | 未预期错误 | | 503 | agent_unavailable | Agent 或队列不可用 | 对越权资源统一返回 404 可减少枚举风险;管理员接口除外。 ## 账户 API ### `POST /auth/register` 请求: - username - slug - email - password - terms_accepted 成功: - user - space - session 副作用: - 创建默认 Space。 - 创建 OA、私人、公开、草稿和归档分类。 - 写 `user.registered` 审计和事件。 ### `POST /auth/login` - 支持用户名或邮箱。 - 记录失败次数和限流。 - 返回安全会话,不返回密码相关字段。 ### `POST /auth/logout` - 撤销当前会话。 ### `GET /me` - 用户资料。 - 套餐。 - 空间摘要。 - 功能开关。 ### `PUT /me/profile` - display_name - slug - bio - avatar_asset_id slug 修改需校验旧链接策略。 ## 空间 API ### `GET /space` 返回 Space、套餐、分类计数和近期内容摘要。 ### `GET /space/quota` 返回: - quota_bytes - used_bytes - reserved_bytes - available_bytes - max_file_bytes - public_page_limit - public_page_used - ai_daily_limit - ai_daily_used ### `GET /space/categories` 返回内置和自定义分类。 ### `GET /space/tree` 参数: - category_id - parent_id - cursor - limit MVP 可只返回一级逻辑目录。 ## 上传和资产 API ### `POST /uploads` 创建 upload session。 请求: - category_id - filename - size_bytes - declared_mime_type - checksum,可选 返回: - upload_id - upload_url 或上传接口 - expires_at - reserved_bytes ### `PUT /uploads/{upload_id}/content` - 流式上传。 - 服务端限制实际字节数。 - 不信任客户端 MIME。 ### `POST /uploads/{upload_id}/complete` - 校验 checksum。 - 完成扫描。 - 创建 Asset 和 AssetVersion。 - 确认配额。 - 幂等。 ### `DELETE /uploads/{upload_id}` - 取消上传并释放预留配额。 ### `GET /assets` 筛选: - category_id - parent_id - asset_type - status - risk_level - source_type - search - cursor ### `GET /assets/{id}` 返回元数据、当前版本、风险摘要、引用关系和允许操作。 ### `GET /assets/{id}/preview` - 私有预览需要认证。 - 返回短期预览 URL 或服务端流。 - 使用安全响应头。 ### `GET /assets/{id}/download` - 记录审计。 - 对私人资产使用短期一次性 URL 或服务端流。 ### `PUT /assets/{id}` 可更新: - display_name - parent_id - category_id 从私人区移动到公开区不能代替脱敏和发布流程。 ### `DELETE /assets/{id}` - 默认软删除。 - 若存在页面或发布引用,返回冲突和引用列表。 ## 页面 API ### `POST /pages` 创建空白页或模板页。 ### `POST /pages/save-from-chat` 请求: - session_id - message_id - title - template_id - target_category_id 服务端验证会话所有权和消息存在。 ### `POST /pages/generate-from-assets` 请求: - asset_ids - instruction - page_type - template_id - output_category_id 返回 Agent job。 ### `GET /pages` 筛选类型、状态、可见性、来源和时间。 ### `GET /pages/{id}` 返回详情、版本、关联资产、发布摘要和允许操作。 ### `PUT /pages/{id}` 请求携带: - expected_version - title - summary - cover_image_asset_id - content - template_id 冲突返回 `version_conflict`。 ### `POST /pages/{id}/versions` 显式创建版本,可用于里程碑保存和发布。 ### `POST /pages/{id}/generate-cover` 创建异步封面任务,输出为新图片资产。 ### `GET /pages/{id}/preview` 返回短期 sandbox 预览入口。 ## 发布 API ### `POST /pages/{id}/publish-check` 请求: - page_version_id - access_mode - url_slug - expires_at 返回: - slug 可用性。 - 安全扫描状态。 - findings。 - 是否允许发布。 ### `POST /pages/{id}/publish` 请求: - page_version_id - access_mode - url_slug - password,可选且只在请求中出现 - expires_at - acknowledged_finding_ids 要求: - `Idempotency-Key`。 - 页面版本不可变。 - 高风险不可通过确认绕过。 ### `POST /publications/{id}/republish` 切换到新页面版本,并保留旧历史。 ### `POST /publications/{id}/offline` 立即下线、失效缓存和写审计。 ### `PUT /publications/{id}/access` 修改密码、过期时间或访问模式。敏感变更需要重新安全检查的条件必须明确。 ### `GET /publications` 按在线、密码、过期和下线筛选。 ### `GET /publications/{id}/stats` 返回总浏览、时间趋势、来源和设备;按套餐裁剪。 ## 安全 API ### `POST /security/scans` 请求目标类型和 ID,重复目标使用幂等 key。 ### `GET /security/scans/{id}` 返回状态、风险级别、摘要和 findings。 ### `POST /security/desensitize` 请求: - source_asset_id - source_version_id - finding_actions - output_category_id 返回脱敏任务。 ### `GET /security/rules` 返回系统和用户规则,隐藏完整自定义正则中的敏感信息。 ### `POST /security/rules` 创建用户规则,需要服务端验证正则复杂度和执行超时风险。 ## Agent Job API ### `POST /agent/jobs` 请求: - job_type - instruction - allowed_assets - output_category_id - output_type 服务端创建绑定,不接受任意文件路径。 ### `GET /agent/jobs/{id}` 返回状态、进度、输出和可重试信息。 ### `POST /agent/jobs/{id}/cancel` 撤销 token,通知执行层停止。 ### `POST /agent/jobs/{id}/retry` 仅允许可重试错误,复用权限快照或要求用户重新授权。 内部执行层接口: - `POST /internal/agent/jobs/{id}/claim` - `GET /internal/agent/jobs/{id}/assets/{asset_id}` - `POST /internal/agent/jobs/{id}/outputs` - `POST /internal/agent/jobs/{id}/heartbeat` - `POST /internal/agent/jobs/{id}/complete` 这些接口使用服务身份和短期 job token,不对浏览器开放。 ## 公开访问 API ### `GET /u/{user_slug}` 只返回用户公开资料和在线 Publication。 ### `GET /u/{user_slug}/pages/{page_slug}` - 检查在线、过期和访问模式。 - 返回发布 bundle。 - 不读取草稿或原始资产。 ### `GET /s/{token}` - 服务端哈希 token 后查询。 - 密码模式建立短期受限访问会话。 - 限流密码尝试。 ### `GET /assets/{public_asset_id}` - 只服务发布 manifest 允许的资源。 - 设置缓存、类型和下载策略。 ## 幂等和重试 必须幂等: - 注册空间初始化。 - upload complete。 - 创建 Agent job。 - 发布和重新发布。 - 脱敏副本生成。 - 异步任务回调。 客户端只对网络失败和明确可重试错误重试,不自动重试校验、权限和安全阻断错误。