Projects
Full CRUD over projects. Tasks reference projects via the project_id field.
A project groups tasks under a single client engagement or initiative. Projects scope visibility — a member added to the project's ProjectMember list sees its tasks; a member without that link sees nothing for that project (except tasks with projectId: null, which are always visible).
Endpoints
| Method | Path | Notes |
|---|---|---|
GET | /api/v1/projects | List. Supports query, status, offset paging. |
POST | /api/v1/projects | Create. Org owner or admin only. Accepts Idempotency-Key. |
GET | /api/v1/projects/{id} | Returns the project plus its members. |
PATCH | /api/v1/projects/{id} | Update. Project manager or org admin. |
DELETE | /api/v1/projects/{id} | Delete. Org owner or admin only. |
Project model
{
"id": "f4c2…",
"organizationId": "1f3c…",
"name": "Acme website redesign",
"description": null,
"clientId": "9b1c…",
"clientName": "Acme Corp",
"status": "inProgress",
"expectedFinalizationDate": "2026-07-15T00:00:00.000Z",
"finalizedAt": null,
"createdAt": "2026-05-01T08:30:00.000Z",
"updatedAt": "2026-05-19T14:22:11.000Z"
}| Field | Type | Notes |
|---|---|---|
status | enum | notStarted · inProgress · onHold · completed · cancelled |
clientId | uuid | null | The linked Client id — this is the input. Setting it copies that client's name into clientName. |
clientName | string | null | Read-only display label, derived from the linked client. |
expectedFinalizationDate | ISO date | null | Planning hint; does not gate finalization. |
finalizedAt | ISO date | null | Set to mark finalized, null to reopen. |
Listing projects
GET /api/v1/projects?status=inProgress&query=acme&limit=25&offset=0| Param | Type | Notes |
|---|---|---|
limit | int 1–100 | Default 50. |
offset | int ≥ 0 | Default 0. |
query | string | Case-insensitive search over name and clientName. |
status | enum | One of the values above. |
Returns { data, total }. Standard members see only projects they're a member of; owner/admin see everything.
Creating a project
POST /api/v1/projects
{
"name": "Acme website redesign",
"clientId": "9b1c…",
"status": "inProgress",
"expectedFinalizationDate": "2026-07-15T00:00:00.000Z"
}Required:
| Field | Type | Constraint |
|---|---|---|
name | string | 1–150 chars |
Optional:
| Field | Type | Constraint |
|---|---|---|
description | string | ≤ 2000 chars |
clientId | uuid | Must reference a client in your org |
status | enum | Defaults to notStarted |
expectedFinalizationDate | ISO date | — |
Response: 201 Created with the new project.
Updating a project
PATCH /api/v1/projects/{id}
{ "status": "completed", "finalizedAt": "2026-05-20T00:00:00.000Z" }All fields are optional. Pass null to clear description, clientId, expectedFinalizationDate, or finalizedAt. An unknown clientId returns 404. Callers must be a manager on the project or an org admin.
Deleting a project
DELETE /api/v1/projects/{id}Returns { "data": { "success": true } }. Org owner or admin only.
Project members
Members are not exposed via REST in v1. Use the in-app Project → Members UI to add or remove people. The GET /projects/{id} response includes the current member roster so external apps can read it.