PJT AIPJT AI/API REFERENCE
v1https://api.pjt.ai/api/external/v1
快速开始MCP
概览认证错误码
Account
  • GET/me
Provisioning
  • POST/provisioning/workspacesENT
Tenants
  • GET/tenants
  • GET/tenants/{tenantId}
Workspaces
  • POST/workspaces
  • GET/workspaces/slug/available
  • GET/workspaces
  • GET/workspaces/{workspaceId}
Projects
  • GET/projects
  • GET/workspaces/{workspaceId}/projects
  • POST/projects
  • GET/projects/{projectId}
  • PUT/projects/{projectId}
  • DELETE/projects/{projectId}
  • GET/projects/{projectId}/timeline
  • GET/projects/{projectId}/activities
  • GET/projects/{projectId}/files
Tasks
  • GET/projects/{projectId}/tasks
  • POST/tasks
  • GET/tasks/{taskId}
  • PUT/tasks/{taskId}
  • DELETE/tasks/{taskId}
  • GET/tasks/assigned
Documents
  • GET/projects/{projectId}/documents
  • GET/documents/{documentId}
  • POST/documents
  • PUT/documents/{documentId}
  • DELETE/documents/{documentId}
OVERVIEW

PJT AI REST API

用于将 PJT AI 数据与外部系统集成的标准 REST API。所有请求与响应均为 JSON,Base URL 为 https://api.pjt.ai/api/external/v1。

基础信息
  • 认证 — X-API-Key 请求头(账号 API 密钥,pjt_ 前缀)
  • 密钥范围 — read(只读,默认)/ write。POST·PUT·DELETE 需要 write 范围的密钥 — 否则返回 403 SCOPE_FORBIDDEN
  • 请求限制 — 每密钥 60 次/分钟 + 每月 10,000 次(Enterprise 可协商)
  • 响应码 — 2xx 成功、4xx 客户端错误、5xx 服务器错误
  • 日期 — 所有时间戳均为 ISO 8601(UTC)
AUTH

认证

每个请求都需要 X-API-Key: <API_KEY> 请求头。密钥在 账号设置 > API 密钥 中签发(仅在创建时显示一次)。

⚠
密钥保管
API 密钥请仅在服务器端使用。一旦暴露给客户端(浏览器/移动应用),应立即吊销并重新签发。
🔑
Key 权限
API Key 以发放它的账号权限运行。在已有租户(tenantId)下创建需要该账号是该租户的 OWNER/ADMIN(否则 403);创建新租户时,该账号成为其 OWNER。发放 provisioning 权限的 Key 仅限 SUPER_ADMIN。
Account
GET/me

我的 API Key(连接测试)

返回 API Key 的有效性与能力(权限范围)。因为是 GET,无需 write 权限——只读 Key 也能查看自身能力。Key 缺失/无效/过期返回 401,这本身就是连接测试结果。用响应中的 canProvision/canWrite/canRead 提前判断能力(例如 canProvision=false 时在预配调用前提示「此 Key 不可用」→避免误报绿灯)。与基础设施 liveness(服务器是否存活)无关。

响应码
200OK401Unauthorized
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

401UNAUTHORIZEDX-API-Key 缺失·无效·过期——这个 401 本身就是「未连接」信号(200 表示已连接)。
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
Provisioning
POST/provisioning/workspaces仅 Enterprise

工作区预配(幂等)

使用 provisioning 权限范围的 API Key 一次性预配租户与工作区。提供 tenantId 时使用该租户(调用 Key 的账号须为 OWNER/ADMIN);否则用 tenantExternalRef 在账号命名空间内幂等查找/创建(两者都无则 400)。workspaceExternalRef 为必填幂等键——重复请求返回已有资源(200)而非新建(201),通过 createdTenant/createdWorkspace 区分。权限层级 provisioning ⊃ write(无需单独 write)。⚠️ businessType 目前不影响结果(仅审计);defaultLocale/accentHue/template 为弱校验(请发送准确取值·未知 template 被忽略);响应 tenant.myRole 可能为 null——不要用于鉴权。

此端点仅在 Enterprise 计划中可用。签发和使用预配权限的 Key 包含在 Enterprise 合约中。

主体参数
名称类型说明
tenantIdinteger已有租户 ID(Long, 可选)。提供时忽略 tenant·tenantExternalRef。调用 Key 的账号须为该租户的 OWNER/ADMIN
tenantExternalRefstring新租户幂等键(≤100, 当无 tenantId 时使用)。相同(账号, 值)复用已有租户
tenant.namestring新租户名称(≤100, 省略时使用 workspace.name)
tenant.slugstring新租户 slug(≤50, 全局唯一·未指定时自动生成)
tenant.descriptionstring新租户描述(≤500)
workspaceExternalRefREQUIREDstring工作区幂等键(≤100, 必填)。相同(tenantId, 值)复用已有工作区
workspace.nameREQUIREDstring工作区名称(≤100, 必填)
workspace.slugstring工作区 slug(≤50, 租户内唯一·未指定时由名称派生)
workspace.descriptionstring工作区描述(≤500)
workspace.defaultLocalestring默认语言 — ko|en|ja|zh|zh-TW|es|vi|th(不校验·请发送准确值)
workspace.accentHueinteger强调色相(0~360, 不校验)
workspace.templatestring预设 — BLANK|DEV|AGENCY|OPS(未知值静默忽略)
workspace.businessTypestring行业类型(前瞻性)——仅审计·不反映到所建工作区
响应码
200OK201Created400Bad Request401Unauthorized403Forbidden429Rate Limited
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

403SCOPE_FORBIDDEN使用只读 Key(无 write 权限)尝试写操作——被网关过滤器拦截
{
  "error": "SCOPE_FORBIDDEN",
  "message": "This API key is read-only. A 'write' scope is required for this operation."
}
403FORBIDDEN缺少 provisioning 权限的 Key——此端点必须 provisioning(仅 write 不够)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "The 'provisioning' scope is required."
}
403FORBIDDEN指定已有 tenantId 时,调用账号不是该租户的 OWNER/ADMIN(或不是成员)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "OWNER or ADMIN role on the tenant is required."
}
400BAD_REQUESTtenantId 与 tenantExternalRef 都未提供
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "One of tenantId or tenantExternalRef is required."
}
400VALIDATION_ERROR校验失败(必填/长度等)——errors[] 内为字段级详情
{
  "timestamp": "2026-07-14T09:00:00Z",
  "code": "VALIDATION_ERROR",
  "message": "workspaceExternalRef: must not be blank",
  "errors": [
    { "field": "workspaceExternalRef", "code": "NotBlank", "message": "must not be blank" }
  ]
}
401UNAUTHORIZEDX-API-Key 缺失·无效·过期(External 通用)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
Tenants
GET/tenants

我的租户

返回 API Key 账号所属的全部租户(租户直接成员 + 仅通过工作区可达的组织=MEMBER)。因为是 GET,具备 read 权限即可。请依据每项的 myRole(OWNER|ADMIN|MEMBER)判定权限——创建工作区(POST /workspaces)仅在 myRole ∈ [OWNER, ADMIN] 的租户上可行,因此 SI 客户端从此列表中挑选 OWNER/ADMIN 项的 id 作为 tenantId 使用。

Response fields
名称类型说明
idLong作为 POST /workspaces 的 tenantId 使用的租户 ID
myRoleString (enum)OWNER | ADMIN | MEMBER(未加入则为 null)。仅可在您为 OWNER/ADMIN 的租户中创建工作区(POST /workspaces)
statusString (enum)租户状态 — ACTIVE | ARCHIVED | DELETE(Tenant.Status)
slugString组织 slug(用于路由)
mfaSetupRequiredboolean若组织强制启用 2FA 且尚未设置则为 true
slugSetboolean用户是否手动设置了 slug(自动生成的 org-xxxx 为 false)
响应码
200OK401Unauthorized
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

401UNAUTHORIZEDX-API-Key 缺失·无效·过期(External 通用)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/tenants/{tenantId}

单个租户

以与列表相同的 shape 返回单个租户。若不属于该租户则访问校验失败(403);不存在的租户返回 400 tenant.not_found。具备 read 权限即可。

路径参数
名称类型说明
tenantIdREQUIREDinteger要查询的租户 ID(Long, 必填)
响应码
200OK400Bad Request401Unauthorized403Forbidden
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

403FORBIDDEN调用账号不是该租户的成员(tenant 访问校验失败)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "테넌트 멤버가 아닙니다"
}
400BAD_REQUEST不存在的租户(tenant.not_found)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "테넌트를 찾을 수 없습니다"
}
401UNAUTHORIZEDX-API-Key 缺失·无效·过期(External 通用)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
Workspaces
POST/workspaces

创建工作区(已有租户)

与预配分离的轻量路径——不创建租户,仅在已有租户(tenantId)下创建工作区。具备 write 权限即可(无需 provisioning·只读 Key 返回 403 SCOPE_FORBIDDEN)。调用 Key 的账号须为该租户的 OWNER/ADMIN。传入 externalRef 则幂等——以相同(tenantId, externalRef)重复请求时返回已有工作区(200)而非新建(201);省略则每次调用都新建(为安全重试建议传入)。所建为团队工作区(非个人)。⚠️ defaultLocale/accentHue/template 为弱校验(取值原样通过·未知 template 被忽略)。若需自动创建租户,请使用预配(POST /provisioning/workspaces)。

主体参数
名称类型说明
tenantIdREQUIREDinteger在此租户下创建(Long, 必填)。调用 Key 的账号须为该租户的 OWNER/ADMIN
externalRefstring幂等键(≤100, 可选)。以相同(tenantId, 值)重复请求时返回已有工作区。省略则每次调用都新建
nameREQUIREDstring工作区名称(≤100, 必填)
slugstring工作区 slug(≤50, 租户内唯一·未指定时由名称派生)
descriptionstring工作区描述(≤500)
defaultLocalestring默认语言 — ko|en|ja|zh|zh-TW|es|vi|th(不校验直接通过·请发送准确值)
accentHueinteger强调色相(0~360, 不校验直接通过)
templatestring预设 — BLANK|DEV|AGENCY|OPS(未知值静默忽略)
响应码
201Created200OK400Bad Request401Unauthorized403Forbidden
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

403SCOPE_FORBIDDEN使用只读 Key(无 write 权限)尝试写操作——被网关过滤器拦截
{
  "error": "SCOPE_FORBIDDEN",
  "message": "This API key is read-only. A 'write' scope is required for this operation."
}
403FORBIDDEN调用账号不是 tenantId 租户的 OWNER/ADMIN(tenant.admin_required)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "관리자 권한이 필요합니다"
}
403FORBIDDEN调用账号不是该租户的成员(含不存在的租户,tenant.not_member)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "테넌트 멤버가 아닙니다"
}
400VALIDATION_ERROR校验失败(缺少 tenantId·name 等)——errors[] 内为字段级详情
{
  "timestamp": "2026-07-14T20:00:00Z",
  "code": "VALIDATION_ERROR",
  "message": "tenantId: must not be null",
  "errors": [
    { "field": "tenantId", "code": "NotNull", "message": "must not be null" }
  ]
}
401UNAUTHORIZEDX-API-Key 缺失·无效·过期(External 通用)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/workspaces/slug/available

检查工作区 slug 是否重复

检查工作区 slug 在租户内是否可用(未被占用)。由于 slug 按 (tenantId, slug) 唯一,因此与创建工作区一样需要 tenantId。slug 会按照保存规则同样进行归一化(去除首尾空格、转小写)后再比较,空值或重复返回 available:false。授权使用与创建工作区相同的门控——调用方必须是该租户的 OWNER/ADMIN(requireTenantAdmin),非成员和非管理员返回 403,且不暴露租户是否存在。由于是 GET,read 权限范围即可。请在创建工作区(POST /workspaces)之前用此 API 预先检查 slug 可用性。

查询参数
名称类型说明
tenantIdREQUIREDinteger在此租户范围内做重复检查(Long,必填 query)。slug 的唯一性范围。调用方必须是此租户的 OWNER/ADMIN
slugREQUIREDstring要检查的工作区 slug(query,必填)。归一化(trim、小写)后比较
Response fields
名称类型说明
availablebooleantrue=可用(未被占用),false=已被占用或为空 slug
响应码
200OK401Unauthorized403Forbidden
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

403FORBIDDEN调用方不是 tenantId 租户的 OWNER/ADMIN(含非成员)——被 requireTenantAdmin 阻止(不暴露租户是否存在)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "관리자 권한이 필요합니다"
}
401UNAUTHORIZEDX-API-Key 缺失、无效或已过期(External 通用)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/workspaces

工作区列表

返回 API 密钥账号可访问的工作区列表。

响应码
200OK401Unauthorized429Rate Limited
GET/workspaces/{workspaceId}

查询工作区

查询单个工作区。

路径参数
名称类型说明
workspaceIdREQUIREDinteger工作区 ID
响应码
200OK401Unauthorized404Not Found
Projects
GET/projects

项目列表(按租户与工作区)

分页返回指定租户与工作区的项目列表。tenantId 与 workspaceId 为必填,可用 status 进一步过滤。

查询参数
名称类型说明
tenantIdREQUIREDinteger租户 ID(必填)
workspaceIdREQUIREDinteger工作区 ID(必填)
statusenum项目状态精确匹配(PLANNING、ESTIMATING、WAITING、IN_PROGRESS、ON_HOLD、COMPLETED、CANCELLED)。指定时也包含已取消/已归档。
pageinteger页码(从 0 开始)
sizeinteger每页大小(默认 20,上限 100)
响应码
200OK400Bad Request401Unauthorized403Forbidden429Rate Limited
错误响应

message 字段按请求语言(?lang 或 Accept-Language)以 8 种语言返回。

400BAD_REQUEST工作区不存在或不属于该租户(跨租户以 not_found 处理,不暴露是否存在)。
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "워크스페이스를 찾을 수 없습니다"
}
400BAD_REQUESTstatus 传入了不支持的值。
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "유효하지 않은 프로젝트 상태 값입니다"
}
403FORBIDDEN无该工作区访问权限(非 ACTIVE 成员且非已接受的客户/合作方 — 无租户成员身份回退)。
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "워크스페이스 접근 권한이 없습니다"
}
401UNAUTHORIZEDX-API-Key 缺失/无效/过期。
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/workspaces/{workspaceId}/projects

项目列表

返回工作区的活跃项目列表(不含已取消/已归档)。

路径参数
名称类型说明
workspaceIdREQUIREDinteger工作区 ID
响应码
200OK401Unauthorized403Forbidden
POST/projects

创建项目(幂等)

创建项目。传入 externalRef 时为幂等操作 — 使用相同 (workspaceId, externalRef) 重复请求时不会新建,而是以 200 返回既有项目(首次创建为 201)。

主体参数
名称类型说明
workspaceIdREQUIREDinteger工作区 ID
nameREQUIREDstring项目名称
externalRefstring幂等键 — 使用相同值重复请求时不会新建,而是以 200 返回既有项目
codestring项目代码(任务键前缀)。省略时根据名称自动生成
descriptionstring描述
clientIdsarray客户 ID 数组
managerIdinteger负责经理的账号 ID
startDatedate开始日期 — ISO 8601 (YYYY-MM-DD)
endDatedate结束日期 — ISO 8601 (YYYY-MM-DD)
budgetinteger预算
响应码
201Created200OK400Bad Request401Unauthorized
GET/projects/{projectId}

项目详情 / 进度

返回项目详情,包含状态、进度(%)、计划/实际日程和最后修改时间。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
响应码
200OK404Not Found
PUT/projects/{projectId}

更新项目

仅更新传入的字段(部分更新)。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
主体参数
名称类型说明
namestring项目名称
statusenum状态 — PLANNING·ESTIMATING·WAITING·IN_PROGRESS·ON_HOLD·COMPLETED·CANCELLED
progressRateinteger进度(%) 0~100
startDatedate开始日期 — ISO 8601 (YYYY-MM-DD)
endDatedate结束日期 — ISO 8601 (YYYY-MM-DD)
响应码
200OK400Bad Request404Not Found
DELETE/projects/{projectId}

删除项目

删除项目。成功时返回 204 No Content(无响应体)。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
响应码
204No Content403Forbidden404Not Found
GET/projects/{projectId}/timeline

时间线(里程碑)

项目里程碑列表 — 名称、状态(PLANNED/IN_PROGRESS/COMPLETED)、截止日期、完成日期和进度。按 sortOrder 排序返回。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
响应码
200OK403Forbidden404Not Found
GET/projects/{projectId}/activities

活动记录

按最新顺序返回项目的任务变更事件 — 类型、消息、操作者和时间。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
查询参数
名称类型说明
pageinteger页码(从 0 开始,默认 0)
sizeinteger每页数量(默认 50,最大 200)
响应码
200OK403Forbidden404Not Found
GET/projects/{projectId}/files

文件列表

合并返回项目内任务和评论的附件,按最新排序。fileUrl 为不过期的静态 URL。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
查询参数
名称类型说明
limitinteger最大数量(默认 100,最大 500)
响应码
200OK403Forbidden404Not Found
Tasks
GET/projects/{projectId}/tasks

任务列表

返回项目的任务列表。需要分页时请使用 /tasks/paged。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
查询参数
名称类型说明
sortBystring排序字段(默认 createdAt)
响应码
200OK403Forbidden404Not Found
POST/tasks

创建任务

创建任务。

主体参数
名称类型说明
projectIdREQUIREDinteger项目 ID(数字)
titleREQUIREDstring标题
descriptionstring描述
assigneeIdinteger负责人账号 ID
statusenum状态 — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED
priorityenum优先级 — URGENT·HIGH·MEDIUM·LOW
dueDatedate截止日期 — ISO 8601
milestoneIdinteger要关联的里程碑 ID
响应码
201Created400Bad Request401Unauthorized
GET/tasks/{taskId}

查询任务

查询单个任务。

路径参数
名称类型说明
taskIdREQUIREDinteger任务 ID
响应码
200OK404Not Found
PUT/tasks/{taskId}

更新任务

仅更新传入的字段。

路径参数
名称类型说明
taskIdREQUIREDinteger任务 ID
主体参数
名称类型说明
titlestring标题
statusenum状态 — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED
priorityenum优先级 — URGENT·HIGH·MEDIUM·LOW
dueDatedate截止日期 — ISO 8601
响应码
200OK400Bad Request404Not Found
DELETE/tasks/{taskId}

删除任务

删除任务。成功时返回 204 No Content。

路径参数
名称类型说明
taskIdREQUIREDinteger任务 ID
响应码
204No Content403Forbidden404Not Found
GET/tasks/assigned

我的任务

返回分配给 API 密钥账号的任务列表。

响应码
200OK401Unauthorized
Documents
GET/projects/{projectId}/documents

文档列表

返回项目的文档列表。需要分页时请使用 /documents/paged。

路径参数
名称类型说明
projectIdREQUIREDstring项目 ID — 数字 ID 或以 p_ 开头的 publicId
响应码
200OK403Forbidden404Not Found
GET/documents/{documentId}

查询文档

查询单个文档(含正文)。

路径参数
名称类型说明
documentIdREQUIREDinteger文档 ID
响应码
200OK404Not Found
POST/documents

创建文档

创建文档。

主体参数
名称类型说明
workspaceIdREQUIREDinteger工作区 ID
titleREQUIREDstring标题
documentTypeREQUIREDenum文档类型(如 REQUIREMENT, MEETING_NOTE)
projectIdinteger项目 ID(数字)
contentstring文档正文
visibilityenum可见范围 — PUBLIC·TEAM·PRIVATE
响应码
201Created400Bad Request401Unauthorized
PUT/documents/{documentId}

更新文档

仅更新传入的字段。

路径参数
名称类型说明
documentIdREQUIREDinteger文档 ID
主体参数
名称类型说明
titlestring标题
contentstring文档正文
visibilityenum可见范围 — PUBLIC·TEAM·PRIVATE
响应码
200OK400Bad Request404Not Found
DELETE/documents/{documentId}

删除文档

删除文档。成功时返回 204 No Content。

路径参数
名称类型说明
documentIdREQUIREDinteger文档 ID
响应码
204No Content403Forbidden404Not Found
ERRORS

错误码

所有错误响应都包含 error.code 和 error.message。

代码名称说明处理
400Bad Request请求体无效。校验请求 body
401UnauthorizedAPI 密钥错误或缺失。重新确认 API 密钥
403Forbidden没有访问该资源的权限。 使用只读密钥发送写入请求时会返回 SCOPE_FORBIDDEN。检查角色/作用域
404Not Found未找到请求的资源。重新确认 ID
429Rate Limited已超过请求限制。参考 Retry-After 头并应用退避
500Server Error服务器处理时发生错误。5 分钟后重试,查看 status.pjt.ai
BASE URL
https://api.pjt.ai/api/external/v1
VERSION
v1 · released 2026-07