openapi: 3.2.0 info: title: Pipeshub Projects API version: 1.0.0 contact: name: API Support email: support@pipeshub.com description: 'Operations tagged Projects across 2 of this provider''s published API definitions: pipeshub-openapi.yaml, pipeshub-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL security: - bearerAuth: [] - oauth2: [] tags: - name: Projects description: 'Workspaces that group related assistant and agent conversations under a shared name, custom instructions, a knowledge scope, and reference files. Projects can be shared with teammates; project membership only grants read access to conversations explicitly marked `projectVisibility: project` — a member never gets access to another member''s private chats. See `Conversations` for the two fields (`projectId`, `projectVisibility`) that link a conversation to a project.' paths: /conversations/{conversationId}/project: put: tags: - Projects summary: Link or unlink a conversation to a project description: 'Set (`projectId: `) or clear (`projectId: null`) the project this conversation belongs to. Initiator-only. **Access:** The caller must be the conversation''s initiator. Linking to a non-null `projectId` also requires at least viewer access to that project (`404` if not visible to the caller — never `403`, to avoid leaking project existence across an org boundary). **Visibility on link:** When linking, `projectVisibility` defaults from the project''s `chatSharing` setting (`members` → `project`, otherwise `private`) unless the conversation was already `project`-visible, in which case that is preserved. Use `PATCH /conversations/{conversationId}/project-visibility` to override it explicitly. Unlinking (`projectId: null`) always clears both `projectId` and `projectVisibility`.' operationId: setConversationProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - projectId properties: projectId: type: - string - 'null' format: objectId description: Target project id, or `null` to unlink. responses: '200': description: Conversation's project link updated content: application/json: schema: type: object additionalProperties: false required: - conversationId properties: conversationId: type: string format: objectId projectId: type: - string - 'null' format: objectId projectVisibility: type: - string - 'null' enum: - private - project '400': description: '`projectId` missing or not a valid ObjectId/`null`.' '401': description: Unauthorized '404': description: 'Conversation not found or caller is not the initiator, or the target project does not exist or is not visible to the caller. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/project-visibility: patch: tags: - Projects summary: Override a conversation's project visibility description: 'Explicitly set whether a project-linked conversation is visible to other members of that project (`project`) or only to its owner (`private`). Initiator-only. Requires the conversation to already be linked to a project via `PUT /conversations/{conversationId}/project`.' operationId: setConversationProjectVisibility x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - visibility properties: visibility: type: string enum: - private - project responses: '200': description: Conversation's project visibility updated content: application/json: schema: type: object additionalProperties: false required: - conversationId - projectVisibility properties: conversationId: type: string format: objectId projectVisibility: type: string enum: - private - project '400': description: '`visibility` missing/invalid, or the conversation is not linked to a project. ' '401': description: Unauthorized '404': description: Conversation not found or caller is not the initiator. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects: post: tags: - Projects summary: Create a project description: Create a new project workspace owned by the caller. operationId: createProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateProjectRequest' responses: '201': description: Project created content: application/json: schema: type: object additionalProperties: false required: - project properties: project: $ref: '#/components/schemas/Project' '400': description: '`name` missing, empty after trimming, or exceeds length limits.' '401': description: Unauthorized get: tags: - Projects summary: List projects description: 'Paginated, non-deleted projects visible to the caller, sorted pinned first then by `lastActivityAt` descending.' operationId: listProjects x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:read parameters: - name: page in: query schema: type: integer minimum: 1 default: 1 - name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 20 - name: search in: query description: Case-insensitive match on project name. schema: type: string maxLength: 200 - name: scope in: query description: '`mine` — owned only. `shared` — projects the caller is a member of. `all` — owned, member, and `visibility: org` projects. Defaults to `mine`. ' schema: type: string enum: - mine - shared - all default: mine - name: includeArchived in: query description: Include archived projects alongside active projects. schema: type: string enum: - 'true' - 'false' default: 'false' - name: isArchived in: query description: 'Filter by exact archive status. When provided, this takes precedence over `includeArchived`. ' schema: type: string enum: - 'true' - 'false' responses: '200': description: Paginated project list content: application/json: schema: type: object additionalProperties: false required: - projects - pagination properties: projects: type: array items: $ref: '#/components/schemas/ProjectListItem' pagination: type: object additionalProperties: false properties: page: type: integer limit: type: integer totalCount: type: integer totalPages: type: integer '401': description: Unauthorized servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}: get: tags: - Projects summary: Get a project description: 'Requires at least viewer access. Cross-org ids and ids the caller cannot see both return `404` — never `403` — to avoid leaking project existence across an org boundary.' operationId: getProjectById x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:read parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project detail content: application/json: schema: type: object additionalProperties: false required: - project properties: project: allOf: - $ref: '#/components/schemas/Project' - type: object properties: role: type: string enum: - owner - editor - viewer readOnly: true '401': description: Unauthorized '404': description: Project not found or not visible to the caller. patch: tags: - Projects summary: Update a project description: 'Requires editor access. `visibility` and `chatSharing` are owner-only fields — including either as a non-owner editor returns `403`.' operationId: updateProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateProjectRequest' responses: '200': description: Project updated content: application/json: schema: type: object additionalProperties: false required: - project properties: project: $ref: '#/components/schemas/Project' '400': description: '`name` provided but empty after trimming, or a field exceeds its length limit.' '401': description: Unauthorized '403': description: Caller can see the project but has only viewer access, or has editor (not owner) access and the request includes `visibility` or `chatSharing`. '404': description: Project not found or not visible to the caller. delete: tags: - Projects summary: Delete a project description: 'Owner-only soft delete. Unlinks every `chatSessions` row pointing at this project (clearing `projectId`/`projectVisibility`) before marking the project deleted, so no conversation is left pointing at a deleted project; wrapped in a transaction when the deployment''s replica set supports it. Idempotent — deleting an already-deleted project returns `200` without re-running the unlink step.' operationId: deleteProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:delete parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project deleted (or already deleted) content: application/json: schema: type: object properties: message: type: string '401': description: Unauthorized '403': description: Caller has access but is not the owner. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/archive: post: tags: - Projects summary: Archive a project description: 'Requires editor access. Archived projects are hidden from the default sidebar but their conversations remain reachable directly.' operationId: archiveProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project archived content: application/json: schema: type: object additionalProperties: false properties: project: $ref: '#/components/schemas/Project' '401': description: Unauthorized '403': description: Caller can see the project but has only viewer access; this action needs editor. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/unarchive: post: tags: - Projects summary: Unarchive a project operationId: unarchiveProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project unarchived content: application/json: schema: type: object additionalProperties: false properties: project: $ref: '#/components/schemas/Project' '401': description: Unauthorized '403': description: Caller can see the project but has only viewer access; this action needs editor. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/pin: post: tags: - Projects summary: Pin a project description: 'Requires viewer access. Pin state is owner-scoped on the document in V1 — pinning affects the project for every viewer, not just the caller (per-user pins are deferred).' operationId: pinProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project pinned content: application/json: schema: type: object additionalProperties: false properties: project: $ref: '#/components/schemas/Project' '401': description: Unauthorized '403': description: Caller can see the project but has only viewer access; this action needs editor. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/unpin: post: tags: - Projects summary: Unpin a project operationId: unpinProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project unpinned content: application/json: schema: type: object additionalProperties: false properties: project: $ref: '#/components/schemas/Project' '401': description: Unauthorized '403': description: Caller can see the project but has only viewer access; this action needs editor. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/conversations: get: tags: - Projects summary: List a project's conversations description: 'Requires viewer access to the project. Returns both chat and agent sessions (`chatSessions`, discriminated by `sessionType`/`agentKey`) that the caller may see: rows they own, plus rows with `projectVisibility: project`. Access to the project is asserted first, so a private conversation belonging to a *different* project member never leaks through this endpoint.' operationId: getProjectConversations x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:read parameters: - name: projectId in: path required: true schema: type: string format: objectId - name: page in: query schema: type: integer minimum: 1 default: 1 - name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: Paginated conversations linked to the project content: application/json: schema: type: object additionalProperties: false required: - conversations - pagination properties: conversations: type: array items: $ref: '#/components/schemas/ConversationListItem' pagination: type: object additionalProperties: false properties: page: type: integer limit: type: integer totalCount: type: integer totalPages: type: integer '401': description: Unauthorized '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/knowledge-base: post: tags: - Projects summary: Ensure (create-if-absent) the project's hidden file Collection description: 'Requires editor access. Lazily creates the project''s own hidden Knowledge Base (`isHidden: true` in Python `POST /api/v1/kb`) the first time a caller needs to upload a file, and returns its id either way. Race-safe: concurrent callers converge on one KB — the losing request''s KB is deleted. The hidden KB is excluded from the Collections sidebar, Knowledge Hub, and unscoped search, but is always included in this project''s own chat scope (`filters.kb`) and file uploads go through the normal `POST /knowledgeBase/{kbId}/upload` SSE pipeline afterward.' operationId: ensureProjectKnowledgeBase x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: The project's linked Collection id (existing or newly created) content: application/json: schema: type: object additionalProperties: false required: - kbId properties: kbId: type: string '401': description: Unauthorized '403': description: Caller can see the project but has only viewer access; this action needs editor. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/members: get: tags: - Projects summary: List project members description: Requires viewer access. operationId: listProjectMembers x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:read parameters: - name: projectId in: path required: true schema: type: string format: objectId responses: '200': description: Project member list (excludes the implicit owner) content: application/json: schema: type: object additionalProperties: false properties: members: type: array items: $ref: '#/components/schemas/ProjectMember' '401': description: Unauthorized '404': description: Project not found or not visible to the caller. put: tags: - Projects summary: Add or update project members description: 'Owner-only. Each `principalId` is validated against this org''s IAM service the same way as `POST /conversations/{conversationId}/share` — a `principalId` with no matching user returns `400`. Upserts by `principalId`; the owner is silently skipped if included.' operationId: upsertProjectMembers x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ProjectMembersUpsertRequest' responses: '200': description: Updated member list content: application/json: schema: type: object additionalProperties: false properties: members: type: array items: $ref: '#/components/schemas/ProjectMember' '400': description: A `principalId` does not exist in this org's IAM service. '401': description: Unauthorized '403': description: Caller has access but is not the owner. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/members/{memberUserId}: delete: tags: - Projects summary: Remove a project member description: Owner-only. operationId: removeProjectMember x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:write parameters: - name: projectId in: path required: true schema: type: string format: objectId - name: memberUserId in: path required: true schema: type: string format: objectId - name: principalType in: query required: false schema: type: string enum: - user - team default: user description: 'Whether `memberUserId` identifies a user or a team. Defaults to `user` when omitted. ' responses: '200': description: Updated member list content: application/json: schema: type: object additionalProperties: false properties: members: type: array items: $ref: '#/components/schemas/ProjectMember' '401': description: Unauthorized '403': description: Caller has access but is not the owner. '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /agents/{agentKey}/conversations/{conversationId}/project: put: tags: - Projects summary: Link or unlink an agent conversation to a project description: 'Agent-conversation equivalent of `PUT /conversations/{conversationId}/project`. Set (`projectId: `) or clear (`projectId: null`) the project this agent conversation belongs to. Initiator-only; linking requires at least viewer access to the target project.' operationId: setAgentConversationProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - agent:write parameters: - name: agentKey in: path required: true schema: type: string - name: conversationId in: path required: true schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - projectId properties: projectId: type: - string - 'null' format: objectId description: Target project id, or `null` to unlink. responses: '200': description: Agent conversation's project link updated content: application/json: schema: type: object additionalProperties: false required: - conversationId properties: conversationId: type: string format: objectId projectId: type: - string - 'null' format: objectId projectVisibility: type: - string - 'null' enum: - private - project '400': description: '`projectId` missing or not a valid ObjectId/`null`.' '401': description: Unauthorized '404': description: 'Agent conversation not found or caller is not the initiator, or the target project does not exist or is not visible to the caller. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /agents/{agentKey}/conversations/{conversationId}/project-visibility: patch: tags: - Projects summary: Override an agent conversation's project visibility description: 'Agent-conversation equivalent of `PATCH /conversations/{conversationId}/project-visibility`. Initiator-only; requires the conversation to already be linked to a project.' operationId: setAgentConversationProjectVisibility x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - agent:write parameters: - name: agentKey in: path required: true schema: type: string - name: conversationId in: path required: true schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - visibility properties: visibility: type: string enum: - private - project responses: '200': description: Agent conversation's project visibility updated content: application/json: schema: type: object additionalProperties: false required: - conversationId - projectVisibility properties: conversationId: type: string format: objectId projectVisibility: type: string enum: - private - project '400': description: '`visibility` missing/invalid, or the conversation is not linked to a project. ' '401': description: Unauthorized '404': description: Agent conversation not found or caller is not the initiator. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL components: schemas: ProjectAppliedFilters: type: object additionalProperties: false description: Display-friendly mirror of `knowledgeScope`, for rendering scope chips without a round trip. properties: apps: type: array items: $ref: '#/components/schemas/AppliedFilterNode' kb: type: array items: $ref: '#/components/schemas/AppliedFilterNode' CreateProjectRequest: type: object additionalProperties: false required: - name properties: name: type: string minLength: 1 maxLength: 100 description: type: string maxLength: 1000 icon: type: string maxLength: 100 color: type: string maxLength: 50 instructions: type: string maxLength: 8000 knowledgeScope: $ref: '#/components/schemas/ProjectKnowledgeScope' appliedFilters: $ref: '#/components/schemas/ProjectAppliedFilters' tools: type: array items: type: string maxItems: 200 AppliedFilterNode: type: object additionalProperties: false description: A single filter node selected by the user (used for display/persistence of active filters) properties: id: type: string description: Unique identifier of the filter node name: type: string description: Display name of the filter node nodeType: type: string description: Type of the node (e.g. app, recordGroup, folder, record) connector: type: string description: Connector identifier associated with this node ProjectKnowledgeScope: type: object additionalProperties: false description: 'Retrieval scope (app connector / knowledge-base ids) inherited by every conversation in the project when the request itself carries no `filters`. Same id shapes as `Filters`. ' properties: apps: type: array items: type: string description: Connector instance ids scoping this project's default retrieval. kb: type: array items: type: string description: Knowledge-base app ids scoping this project's default retrieval. UpdateProjectRequest: type: object additionalProperties: false description: 'All fields optional; only supplied fields are updated. `visibility`/`chatSharing` are owner-only — an editor who is not the owner gets `403` if they include either field. Flattened (not `allOf: [CreateProjectRequest, ...]`) since `CreateProjectRequest` itself is `additionalProperties: false` — composing two closed schemas would reject `visibility`/`chatSharing` on every real update. ' properties: name: type: string minLength: 1 maxLength: 100 description: type: string maxLength: 1000 icon: type: string maxLength: 100 color: type: string maxLength: 50 instructions: type: string maxLength: 8000 knowledgeScope: $ref: '#/components/schemas/ProjectKnowledgeScope' appliedFilters: $ref: '#/components/schemas/ProjectAppliedFilters' tools: type: array items: type: string maxItems: 200 visibility: type: string enum: - private - org chatSharing: type: string enum: - private - members Project: type: object description: 'A workspace that groups related assistant and agent conversations under a shared name, instructions, knowledge scope, tool selection, and its own hidden Collection of uploaded files. See the `Projects` tag description for the sharing model. ' properties: _id: type: string format: objectId orgId: type: string format: objectId userId: type: string format: objectId description: Owner. Ownership never transfers. name: type: string maxLength: 100 description: type: string maxLength: 1000 icon: type: string color: type: string instructions: type: string maxLength: 8000 description: 'Injected into every conversation in this project as a dedicated, author-attributed `project_instructions` prompt section — additive, never overrides agent identity or system prompts. ' knowledgeScope: $ref: '#/components/schemas/ProjectKnowledgeScope' appliedFilters: $ref: '#/components/schemas/ProjectAppliedFilters' tools: type: array items: type: string description: 'Tool fullNames (toolset + MCP tools, same format as the composer''s `agentStreamTools`) this project''s agent-mode chats may use. Empty means no tools beyond the project''s own files. ' linkedKnowledgeBaseId: type: - string - 'null' readOnly: true description: 'Id of the hidden Collection holding this project''s uploaded files, created lazily on first upload via `POST /projects/{projectId}/knowledge-base`. `null` until then. ' visibility: type: string enum: - private - org default: private description: '`org` makes the project (and, per `chatSharing`, its `project`-visible conversations) readable by every member of the organization, without adding them to `members[]`. Also grants the organization''s synthetic all-members team `READER` access on the linked hidden Collection. ' chatSharing: type: string enum: - private - members default: private description: 'Owner-controlled default for new conversations created in this project. `private` keeps new chats visible to their own owner only; `members` exposes them to every project member (`projectVisibility: project`). A conversation''s own `projectVisibility` can override this default per-chat. ' members: type: array items: $ref: '#/components/schemas/ProjectMember' isPinned: type: boolean default: false description: Owner-scoped pin state in V1 (not per-viewer). isArchived: type: boolean default: false archivedBy: type: - string - 'null' format: objectId isDeleted: type: boolean default: false deletedBy: type: - string - 'null' format: objectId lastActivityAt: type: integer format: int64 description: Epoch milliseconds, bumped whenever a linked conversation streams a turn. metadata: type: object additionalProperties: true createdAt: type: string format: date-time updatedAt: type: string format: date-time ConversationSharedBy: type: object additionalProperties: false description: 'Present on conversations the caller received via share. Identifies the conversation initiator (the only user who can share a chat). ' required: - userId - name properties: userId: type: string format: objectId name: type: string description: Display name, falling back to email or the user id ProjectMembersUpsertRequest: type: object additionalProperties: false required: - members properties: members: type: array items: type: object additionalProperties: false required: - principalId - role properties: principalId: type: string format: objectId description: 'User id to add or update. Must exist in this org''s IAM service (validated the same way as `POST /conversations/{conversationId}/share`). ' role: type: string enum: - viewer - editor description: 'Upserted by `principalId`: existing members get their `role` updated, new ids are added. The project owner is silently skipped if included (ownership is implicit). ' ConversationListItem: type: object description: 'Conversation summary returned by list endpoints. Identical to `Conversation` but omits `messages` to keep list payloads small. Fetch a single conversation to retrieve its messages. ' properties: _id: type: string format: objectId userId: type: string format: objectId orgId: type: string format: objectId title: type: string initiator: type: string format: objectId status: type: string enum: - None - Inprogress - Complete - Failed - Stopped failReason: type: string modelInfo: type: object properties: modelKey: type: string modelName: type: string modelFriendlyName: type: string modelProvider: type: string chatMode: type: string isShared: type: boolean shareLink: type: string sharedWith: type: array items: type: object properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write isArchived: type: boolean archivedBy: type: - string - 'null' format: objectId description: 'User ID of the last user who archived this row, or `null` after unarchive cleared the archive state. Absent on rows that have never been archived. ' isDeleted: type: boolean deletedBy: type: string format: objectId conversationErrors: type: array items: type: object properties: message: type: string errorType: type: string timestamp: type: string format: date-time messageId: type: string format: objectId stack: type: string metadata: type: object additionalProperties: true metadata: type: object additionalProperties: true lastActivityAt: type: integer createdAt: type: string format: date-time updatedAt: type: string format: date-time isOwner: type: boolean readOnly: true accessLevel: type: string enum: - read - write readOnly: true projectId: type: - string - 'null' format: objectId description: 'The project this conversation is linked to, if any. Set via `PUT /conversations/{conversationId}/project` or at creation time; absent on conversations that were never linked. ' projectVisibility: type: - string - 'null' enum: - private - project description: 'Only meaningful when `projectId` is set. `private` (default) keeps the conversation visible to its owner only; `project` exposes it to every member of the linked project. See `PATCH /conversations/{conversationId}/project-visibility`. ' sharedBy: $ref: '#/components/schemas/ConversationSharedBy' ProjectMember: type: object additionalProperties: false required: - principalType - principalId - role - addedBy - addedAt properties: principalType: type: string enum: - user - team description: Whether `principalId` names a user or a team. Both grant the same `role`, mirroring Collection sharing. principalId: type: string format: objectId description: User or team id of the member. The project owner is implicit and never appears in this list. role: type: string enum: - viewer - editor description: '`viewer` can read the project and its `project`-visible conversations. `editor` can additionally update project metadata, instructions, scope, tools, and files. Only the owner can manage members or change `visibility`/`chatSharing`. ' addedBy: type: string format: objectId addedAt: type: string format: date-time ProjectListItem: allOf: - $ref: '#/components/schemas/Project' - type: object description: Project summary returned by `GET /projects`, enriched with request-computed fields. properties: role: type: string enum: - owner - editor - viewer readOnly: true description: 'Caller''s effective role on this project (owner, explicit member role, or `viewer` via `visibility: org`). ' conversationCount: type: integer minimum: 0 readOnly: true description: Count of non-deleted conversations (chat + agent) linked to this project. securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: 'JWT Bearer token for authenticated requests. A personal access token (see the **Personal Access Tokens** tag) is a `phpat_`-prefixed variant of this same JWT — e.g. `phpat_eyJhbGci...`. The prefix is display-only, added for secret-scanner detectability; the gateway strips it before verifying the token, so send it exactly as issued, prefix included. ' scopedToken: type: http scheme: bearer bearerFormat: JWT description: 'Scoped JWT token for service-to-service authentication. Format: "Bearer {scoped_token}" Required scopes vary by endpoint. ' oauth2: type: oauth2 description: 'OAuth 2.0 authentication with fine-grained scopes. Supports authorization_code (with PKCE) and client_credentials flows. OAuth tokens are Bearer JWTs — use the same Authorization header as regular tokens. For **client_credentials**, machine JWTs may use `userId === client_id`; the Node gateway resolves the OAuth app creator — see **OAuth Provider** tag. ' flows: authorizationCode: authorizationUrl: /api/v1/oauth2/authorize tokenUrl: /api/v1/oauth2/token refreshUrl: /api/v1/oauth2/token scopes: openid: OpenID Connect authentication profile: User profile information email: User email address offline_access: Offline access (refresh tokens) org:read: Read organization information org:write: Update organization settings org:admin: Full organization administration user:read: Read user profiles user:write: Update user profiles user:invite: Invite new users user:delete: Delete users usergroup:read: Read user groups usergroup:write: Create and manage user groups team:read: Read team information team:write: Create and manage teams kb:read: Read knowledge bases and records kb:write: Create and update knowledge bases kb:delete: Delete knowledge bases and records kb:upload: Upload files to knowledge bases semantic:read: Read semantic search results and history semantic:write: Execute semantic search semantic:delete: Delete semantic search history conversation:read: Read conversations conversation:write: Create and manage conversations conversation:chat: Send messages in conversations project:read: Read projects and their conversations project:write: Create and manage projects project:delete: Delete projects agent:read: Read AI agents agent:write: Create and manage AI agents agent:execute: Execute AI agents connector:read: Read connector configurations connector:write: Create and update connectors connector:sync: Trigger connector synchronization connector:delete: Delete connectors config:read: Read system configuration config:write: Update system configuration crawl:read: Read crawling jobs crawl:write: Create and manage crawling jobs crawl:delete: Delete crawling jobs clientCredentials: tokenUrl: /api/v1/oauth2/token scopes: openid: OpenID Connect authentication profile: User profile information email: User email address offline_access: Offline access (refresh tokens) org:read: Read organization information org:write: Update organization settings org:admin: Full organization administration user:read: Read user profiles user:write: Update user profiles user:invite: Invite new users user:delete: Delete users usergroup:read: Read user groups usergroup:write: Create and manage user groups team:read: Read team information team:write: Create and manage teams kb:read: Read knowledge bases and records kb:write: Create and update knowledge bases kb:delete: Delete knowledge bases and records kb:upload: Upload files to knowledge bases semantic:write: Execute semantic search semantic:read: Read semantic search results and history semantic:delete: Delete semantic search history conversation:read: Read conversations conversation:write: Create and manage conversations conversation:chat: Send messages in conversations project:read: Read projects and their conversations project:write: Create and manage projects project:delete: Delete projects agent:read: Read AI agents agent:write: Create and manage AI agents agent:execute: Execute AI agents connector:read: Read connector configurations connector:write: Create and update connectors connector:sync: Trigger connector synchronization connector:delete: Delete connectors config:read: Read system configuration config:write: Update system configuration crawl:read: Read crawling jobs crawl:write: Create and manage crawling jobs x-refined-from: - pipeshub-openapi.yaml - pipeshub-openapi.yml