Close an ACTIVE conversation manually. Only the project owner can close a conversation. The conversation must be currently ACTIVE.
- Closing sets the conversation
statustoCLOSED. - Already CLOSED conversations cannot be closed again — a 409 Conflict is returned.
- The response returns the updated conversation metadata without the message list.
- Closed conversations remain readable via UC-04004 (Conversation Detail).
sequenceDiagram
actor User
User->>+FE: clicks "Close Conversation"
FE->>+BE: PUT /api/v1/projects/{projectId}/conversations/{conversationId}/close <br> Authorization: Bearer {accessToken}
BE->>BE: validate access token
alt token missing or invalid
BE-->>FE: 401 Unauthorized <br> ErrorResponse
end
BE->>DB: load project by projectId
alt project not found
BE-->>FE: 404 Not Found <br> ErrorResponse
end
BE->>BE: check project belongs to user's tenant
alt project does not belong to tenant
BE-->>FE: 403 Forbidden <br> ErrorResponse
end
BE->>DB: load conversation by conversationId (scoped to projectId)
alt conversation not found
BE-->>FE: 404 Not Found <br> ErrorResponse
end
BE->>BE: check conversation status is ACTIVE
alt conversation is already CLOSED
BE-->>FE: 409 Conflict <br> ErrorResponse
end
BE->>DB: update conversation status = CLOSED
BE->>-FE: 200 OK <br> ConversationResponse
FE->>-User: update conversation status in UI
PUT /api/v1/projects/{projectId}/conversations/{conversationId}/close (no request body)
200 OK ConversationResponse:
{
"data": {
"id": 8,
"title": "I want to add a contact form to the homepage",
"status": "CLOSED",
"messageCount": 4,
"createdAt": "2026-04-29T12:00:00Z",
"updatedAt": "2026-04-29T12:15:01Z"
}
}
401 Unauthorized (missing or invalid access token) ErrorResponse:
{
"status": 401,
"code": "AUTHENTICATION_FAILED",
"message": "Access token is missing or invalid"
}
403 Forbidden (project does not belong to user’s tenant) ErrorResponse:
{
"status": 403,
"code": "FORBIDDEN",
"message": "You do not have access to this project"
}
404 Not Found (project not found) ErrorResponse:
{
"status": 404,
"code": "NOT_FOUND_PROJECT",
"message": "Project not found"
}
404 Not Found (conversation not found or does not belong to project) ErrorResponse:
{
"status": 404,
"code": "NOT_FOUND_CONVERSATION",
"message": "Conversation not found"
}
409 Conflict (conversation is already CLOSED) ErrorResponse:
{
"status": 409,
"code": "CONFLICT_CONVERSATION",
"message": "Conversation is already CLOSED"
}
Frontend
Validations
| Field | Constraints | Size | Pattern | Note |
|---|---|---|---|---|
| (no request body) | — | — | — | This endpoint takes no request body |
Backend
Validations
| Field | Constraints | Size | Pattern | Note |
|---|---|---|---|---|
| projectId | not_null, positive | — | — | Path variable; must reference an existing project |
| conversationId | not_null, positive | — | — | Path variable; must reference a conversation belonging to the project |
Test Cases
| GIVEN | WHEN | THEN |
|---|---|---|
| authenticated user, ACTIVE conversation | PUT /conversations/{conversationId}/close is called | 200 OK with updated conversation status=CLOSED |
| authenticated user, already CLOSED conversation | PUT /conversations/{conversationId}/close is called | 409 CONFLICT_CONVERSATION error response is returned |
| authenticated user, conversation does not exist | PUT /conversations/{conversationId}/close is called | 404 NOT_FOUND_CONVERSATION error response is returned |
| authenticated user, conversation belongs to a different project | PUT /conversations/{conversationId}/close is called | 404 NOT_FOUND_CONVERSATION error response is returned |
| authenticated user, project does not exist | PUT /conversations/{conversationId}/close is called | 404 NOT_FOUND_PROJECT error response is returned |
| authenticated user, project belongs to a different tenant | PUT /conversations/{conversationId}/close is called | 403 FORBIDDEN error response is returned |
| no Authorization header | PUT /conversations/{conversationId}/close is called | 401 AUTHENTICATION_FAILED error response is returned |
Was this page helpful?
Thanks for the feedback.