Comments API¶
!!! info "TL;DR" Discussion threads on submissions. Public read, authenticated write. Official badge for team members. Nested replies supported.
List Comments¶
Get all comments for a submission.
Authentication: Optional
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
page | number | Page number (default: 1) |
limit | number | Items per page (default: 50) |
sort | string | created_at or votes (default: created_at) |
order | string | asc or desc (default: asc) |
Example Request:
Example Response:
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"body": "This would be really helpful for late-night use!",
"author": {
"id": "uuid",
"name": "Jane Doe",
"avatar": "https://cdn.canviq.app/avatars/...",
"is_team_member": false
},
"is_official": false,
"vote_count": 5,
"reply_count": 2,
"parent_id": null,
"created_at": "2026-01-16T08:30:00Z",
"updated_at": "2026-01-16T08:30:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440011",
"body": "We've planned this for Q2 2026. Thanks for the feedback!",
"author": {
"id": "uuid",
"name": "Product Team",
"avatar": "...",
"is_team_member": true
},
"is_official": true,
"vote_count": 12,
"reply_count": 0,
"parent_id": null,
"created_at": "2026-02-01T14:20:00Z",
"updated_at": "2026-02-01T14:20:00Z"
}
],
"meta": {
"total": 8
}
}
Get Comment¶
Get a single comment by ID with nested replies.
Authentication: Optional
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
expand | string | replies to include nested comments |
Example Request:
Example Response:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440010",
"body": "This would be really helpful!",
"author": {...},
"replies": [
{
"id": "550e8400-e29b-41d4-a716-446655440012",
"body": "Agreed! Especially on mobile.",
"author": {...},
"parent_id": "550e8400-e29b-41d4-a716-446655440010",
"created_at": "2026-01-16T09:00:00Z"
}
],
"created_at": "2026-01-16T08:30:00Z"
}
}
Create Comment¶
Add a comment to a submission.
Authentication: Required
Request Body:
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
body | string | Yes | 1-2000 characters |
parent_id | UUID | No | Parent comment for nested replies |
Example Request:
curl -X POST https://canviq.app/api/submissions/550e8400-e29b-41d4-a716-446655440000/comments \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"body": "This would be really helpful!",
"parent_id": null
}'
Example Response:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440013",
"body": "This would be really helpful!",
"author": {
"id": "uuid",
"name": "Your Name"
},
"is_official": false,
"created_at": "2026-02-10T15:45:00Z"
}
}
Side Effects:
- Increments
comment_counton submission (via trigger) - Sends notification to submission author
- Sends notification to parent comment author (if replying)
- Sends notification to all followers
Update Comment¶
Edit a comment (author only, within 15 minutes).
Authentication: Required (must be author)
Request Body:
Example Request:
curl -X PATCH https://canviq.app/api/comments/550e8400-e29b-41d4-a716-446655440010 \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"body": "Updated comment text"}'
Comments can only be edited within 15 minutes of creation. After that, the endpoint returns 403 Forbidden.
Delete Comment¶
Delete a comment (author or admin).
Authentication: Required (must be author or admin)
Example Request:
curl -X DELETE https://canviq.app/api/comments/550e8400-e29b-41d4-a716-446655440010 \
-H "Authorization: Bearer your-api-key"
Example Response:
Deleting a parent comment also deletes all nested replies (cascade).
Official Comments¶
Team members can post official comments that get a special badge. Official comments:
- Display an "Official" badge
- Appear at the top of comment threads (sorted first)
- Send notifications to all followers
- Are used in submission status updates
To post an official comment, the author must be in the team_members table. The is_official flag is set automatically based on team membership.
Vote on Comments¶
Comments support voting just like submissions.
Works identically to submission voting. Useful for surfacing helpful comments.
Realtime Comment Updates¶
Subscribe to new comments via Supabase Realtime:
const channel = supabase
.channel(`comments:submission=${submissionId}`)
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'comments',
filter: `submission_id=eq.${submissionId}`,
},
(payload) => {
console.log('New comment:', payload.new)
// Update UI with new comment
}
)
.subscribe()
Rate Limits¶
| Endpoint | Limit | Window |
|---|---|---|
POST /comments | 20 | 1 hour |
PATCH /comments/:id | 10 | 1 hour |
DELETE /comments/:id | 10 | 1 hour |
GET /comments | 100 | 1 minute |
What's Next¶
- Submissions API — Parent submissions
- Notifications — Email digests and alerts
- Moderation — Spam detection and content flags