PJT AI REST API
A standard REST API for integrating PJT AI data with external systems. All requests and responses are JSON, and the base URL is https://api.pjt.ai/api/external/v1.
- Authentication — X-API-Key header (account API key, pjt_ prefix)
- Key scopes — read (read-only, default) / write. POST·PUT·DELETE require a write-scoped key — otherwise 403 SCOPE_FORBIDDEN
- Rate limit — 60 req/min + 10,000 req/month per key (Enterprise by arrangement)
- Response codes — 2xx success, 4xx client error, 5xx server error
- Dates — all timestamps are ISO 8601 (UTC)
Authentication
Every request requires the X-API-Key: <API_KEY> header. Issue keys under Account Settings > API keys (shown only once at creation).
/workspacesList workspaces
Returns the workspaces accessible to the API-key account.
/workspaces/{workspaceId}Get workspace
Returns a single workspace.
| Name | Type | Description |
|---|---|---|
| workspaceIdREQUIRED | integer | Workspace ID |
/workspaces/{workspaceId}/projectsList projects
Returns the active projects of a workspace (cancelled/archived excluded).
| Name | Type | Description |
|---|---|---|
| workspaceIdREQUIRED | integer | Workspace ID |
/projectsCreate project (idempotent)
Creates a project. With externalRef the call is idempotent — repeating the same (workspaceId, externalRef) returns the existing project with 200 instead of creating a new one (201 on first creation).
| Name | Type | Description |
|---|---|---|
| workspaceIdREQUIRED | integer | Workspace ID |
| nameREQUIRED | string | Project name |
| externalRef | string | Idempotency key — repeating with the same value returns the existing project with 200 instead of creating a new one |
| code | string | Project code (task key prefix). Auto-generated from the name if omitted |
| description | string | Description |
| clientIds | array | Array of client IDs |
| managerId | integer | Manager account ID |
| startDate | date | Start date — ISO 8601 (YYYY-MM-DD) |
| endDate | date | End date — ISO 8601 (YYYY-MM-DD) |
| budget | integer | Budget |
/projects/{projectId}Get project / progress
Returns project detail including status, progress (%), planned/actual dates and last-modified time.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
/projects/{projectId}Update project
Updates only the fields you send (partial update).
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
| Name | Type | Description |
|---|---|---|
| name | string | Project name |
| status | enum | Status — PLANNING·ESTIMATING·WAITING·IN_PROGRESS·ON_HOLD·COMPLETED·CANCELLED |
| progressRate | integer | Progress (%) 0–100 |
| startDate | date | Start date — ISO 8601 (YYYY-MM-DD) |
| endDate | date | End date — ISO 8601 (YYYY-MM-DD) |
/projects/{projectId}Delete project
Deletes a project. Returns 204 No Content on success (empty body).
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
/projects/{projectId}/timelineTimeline (milestones)
Project milestones — name, status (PLANNED/IN_PROGRESS/COMPLETED), due date, completion date and progress. Ordered by sortOrder.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
/projects/{projectId}/activitiesActivities
Task change events of the project, newest first — type, message, actor and timestamp.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
| Name | Type | Description |
|---|---|---|
| page | integer | Page number (0-based, default 0) |
| size | integer | Page size (default 50, max 200) |
/projects/{projectId}/filesFiles
Task and comment attachments of the project merged, newest first. fileUrl is a static, non-expiring URL.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
| Name | Type | Description |
|---|---|---|
| limit | integer | Maximum items (default 100, max 500) |
/projects/{projectId}/tasksList tasks
Returns the tasks of a project. Use /tasks/paged when you need pagination.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
| Name | Type | Description |
|---|---|---|
| sortBy | string | Sort field (default createdAt) |
/tasksCreate task
Creates a task.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | integer | Project ID (numeric) |
| titleREQUIRED | string | Title |
| description | string | Description |
| assigneeId | integer | Assignee account ID |
| status | enum | Status — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED |
| priority | enum | Priority — URGENT·HIGH·MEDIUM·LOW |
| dueDate | date | Due date — ISO 8601 |
| milestoneId | integer | Milestone ID to link |
/tasks/{taskId}Get task
Returns a single task.
| Name | Type | Description |
|---|---|---|
| taskIdREQUIRED | integer | Task ID |
/tasks/{taskId}Update task
Updates only the fields you send.
| Name | Type | Description |
|---|---|---|
| taskIdREQUIRED | integer | Task ID |
| Name | Type | Description |
|---|---|---|
| title | string | Title |
| status | enum | Status — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED |
| priority | enum | Priority — URGENT·HIGH·MEDIUM·LOW |
| dueDate | date | Due date — ISO 8601 |
/tasks/{taskId}Delete task
Deletes a task. Returns 204 No Content on success.
| Name | Type | Description |
|---|---|---|
| taskIdREQUIRED | integer | Task ID |
/tasks/assignedMy assigned tasks
Returns the tasks assigned to the API-key account.
/projects/{projectId}/documentsList documents
Returns the documents of a project. Use /documents/paged when you need pagination.
| Name | Type | Description |
|---|---|---|
| projectIdREQUIRED | string | Project ID — numeric ID or publicId starting with p_ |
/documents/{documentId}Get document
Returns a single document including its content.
| Name | Type | Description |
|---|---|---|
| documentIdREQUIRED | integer | Document ID |
/documentsCreate document
Creates a document.
| Name | Type | Description |
|---|---|---|
| workspaceIdREQUIRED | integer | Workspace ID |
| titleREQUIRED | string | Title |
| documentTypeREQUIRED | enum | Document type (e.g. REQUIREMENT, MEETING_NOTE) |
| projectId | integer | Project ID (numeric) |
| content | string | Document body |
| visibility | enum | Visibility — PUBLIC·TEAM·PRIVATE |
/documents/{documentId}Update document
Updates only the fields you send.
| Name | Type | Description |
|---|---|---|
| documentIdREQUIRED | integer | Document ID |
| Name | Type | Description |
|---|---|---|
| title | string | Title |
| content | string | Document body |
| visibility | enum | Visibility — PUBLIC·TEAM·PRIVATE |
/documents/{documentId}Delete document
Deletes a document. Returns 204 No Content on success.
| Name | Type | Description |
|---|---|---|
| documentIdREQUIRED | integer | Document ID |
Error codes
Every error response includes error.code and error.message.
| Code | Name | Description | Action |
|---|---|---|---|
| 400 | Bad Request | The request body is invalid. | Validate the request body |
| 401 | Unauthorized | The API key is invalid or missing. | Re-check the API key |
| 403 | Forbidden | You don't have permission to access this resource. Write requests with a read-only key return SCOPE_FORBIDDEN. | Check roles/scopes |
| 404 | Not Found | The requested resource was not found. | Re-check the ID |
| 429 | Rate Limited | You exceeded the rate limit. | See the Retry-After header and back off |
| 500 | Server Error | An error occurred while the server processed the request. | Retry after 5 min, check status.pjt.ai |