Projects

Create and manage projects — the primary workspace unit that groups entities, files, tasks, and views within an organization. The organization is taken from the authenticated session; callers never pass `org_id`. Identifiers and timestamps are assigned by the platform.

9 endpoints. Generated from the OpenAPI 3.1 specification.

GET /v1/projects

List projects

Returns the projects in the caller's organization that the caller can see, with offset pagination. Requires a valid session; the organization and RLS scope are derived from the access token.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
status query string no Filter by lifecycle status (e.g. `active`, `archived`). Omit for the default active set.
limit query integer no Maximum number of projects to return (1–100, default 50).
offset query integer no Number of projects to skip for pagination.

Responses

StatusDescription
200 Paginated list of projects.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/projects

Create a project

Creates a new project in the caller's organization. The only required field is `name`. A URL-safe `slug` is generated from the name when omitted. The organization is taken from the session — `org_id` is never accepted in the body. Returns the full created record, including the platform-assigned `id`, `slug`, `is_active`, and timestamps.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes Project name.
slug string no Optional canonical slug (lowercase alphanumeric with single internal hyphens, not UUID-shaped). Auto-generated from the name when omitted; reserved words are rejected.
description string no Optional project summary.
settings object no Optional bounded settings object.
{
  "name": "Q2 Client Onboarding"
}

Responses

StatusDescription
201 Project created. The full project record is returned under `data`.
400 `INVALID_JSON` (unparseable body), `VALIDATION_ERROR` (a field failed validation, including a non-canonical or reserved `slug` → message names `RESERVED_SLUG`/`INVALID_FORMAT`).
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 `PERMISSION_DENIED` (missing the `project.create` permission) or `PROJECT_LIMIT_REACHED` (the organization's plan project limit is reached).
409 `PROJECT_SLUG_EXISTS` — a project with that slug already exists in this organization and environment.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid> Platform-assigned project identifier (UUIDv7).
org_id string<uuid> Owning organization.
name string Display name (1–255 chars).
slug string URL-safe slug (unique per org+environment). Auto-generated from the name when not supplied.
description string | null Optional summary (≤4096 chars).
prefix string | null Optional short prefix used for human-friendly entity ids.
visibility string (enum) publicprivateinternal Project visibility.
category_id string | null Optional project category.
owner_scope string Ownership scope (e.g. `organization`).
is_active boolean False when archived or soft-deleted.
created_by_user_id string | null User who created the project.
created_at string<date-time> Creation timestamp (assigned by the platform).
updated_at string<date-time> Last-update timestamp.
settings object Project settings object.
GET /v1/projects/{projectId}

Get a project

Returns a single project by id. A project the caller cannot see is reported as `404 NOT_FOUND` (indistinguishable from a missing one, per the anti-enumeration contract).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).

Responses

StatusDescription
200 The project record.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid> Platform-assigned project identifier (UUIDv7).
org_id string<uuid> Owning organization.
name string Display name (1–255 chars).
slug string URL-safe slug (unique per org+environment). Auto-generated from the name when not supplied.
description string | null Optional summary (≤4096 chars).
prefix string | null Optional short prefix used for human-friendly entity ids.
visibility string (enum) publicprivateinternal Project visibility.
category_id string | null Optional project category.
owner_scope string Ownership scope (e.g. `organization`).
is_active boolean False when archived or soft-deleted.
created_by_user_id string | null User who created the project.
created_at string<date-time> Creation timestamp (assigned by the platform).
updated_at string<date-time> Last-update timestamp.
settings object Project settings object.
PUT /v1/projects/{projectId}

Update a project

Updates a project's name, slug, description, visibility, archive state, or settings. At least one field must be provided. `description: null` clears the description; `is_active` toggles archive/active.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no New name.
slug string no New canonical slug.
description string | null no New description; null clears it.
visibility string (enum) publicprivateinternal no New visibility.
is_active boolean no Archive (false) / unarchive (true).
settings object no Replacement settings object.

Responses

StatusDescription
200 The updated project record.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `PROJECT_SLUG_EXISTS` — the requested slug is already taken in this organization.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid> Platform-assigned project identifier (UUIDv7).
org_id string<uuid> Owning organization.
name string Display name (1–255 chars).
slug string URL-safe slug (unique per org+environment). Auto-generated from the name when not supplied.
description string | null Optional summary (≤4096 chars).
prefix string | null Optional short prefix used for human-friendly entity ids.
visibility string (enum) publicprivateinternal Project visibility.
category_id string | null Optional project category.
owner_scope string Ownership scope (e.g. `organization`).
is_active boolean False when archived or soft-deleted.
created_by_user_id string | null User who created the project.
created_at string<date-time> Creation timestamp (assigned by the platform).
updated_at string<date-time> Last-update timestamp.
settings object Project settings object.
DELETE /v1/projects/{projectId}

Delete (archive) a project

Soft-deletes a project by setting `is_active = false`. The underlying data is preserved for recovery and the audit trail; the project is hidden from listings.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).

Responses

StatusDescription
200 The project was soft-deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
is_active boolean (enum) false
GET /v1/projects/{projectId}/members

List project members

Returns the members of a project with offset pagination.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).
limit query integer no Maximum number of records to return. Default and ceiling are endpoint-specific (commonly default 25–50, max 100).
offset query integer no Number of records to skip for offset pagination.

Responses

StatusDescription
200 Paginated list of project members.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/projects/{projectId}/members

Add a project member

Adds a user to the project with a role. The acting user must have permission to manage project membership.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
user_id string<uuid> yes User to add (UUIDv7).
role string yes Role to grant within the project.
{
  "user_id": "019b0000-0000-7000-8000-000000000000",
  "role": "editor"
}

Responses

StatusDescription
201 The member was added.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
user_id string<uuid> Member user id.
project_id string<uuid> Project id.
role string Member's role within the project.
display_name string | null Member display name.
email string | null Member email.
created_at string<date-time> When the membership was created.
DELETE /v1/projects/{projectId}/members/{userId}

Remove a project member

Removes a user from the project. A non-existent or cross-tenant project is reported as `404 NOT_FOUND`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).
userId path string<uuid> yes The user to remove (UUIDv7).

Responses

StatusDescription
200 The member was removed.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PUT /v1/projects/{projectId}/settings

Upsert project settings

Replaces the project's settings JSON object. The body is a bounded JSON object validated for size and depth.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
projectId path string<uuid> yes Project identifier (UUIDv7).

Request Body

Arbitrary bounded settings object (size/depth limited).

Responses

StatusDescription
200 The settings were saved.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.