REST API Reference
Full API for managing feedback, votes, comments, changelog, and roadmap programmatically.
Authentication
Reflet uses two types of API keys to separate read and write operations.
Public Key pk_...
Passed as a query parameter. Used for read-only operations that are safe to call from client-side code.
GET /api/v1/feedback?publicKey=pk_your_public_keySecret Key sk_...
Passed as an Authorization header. Used for write operations and should only be used from server-side code.
Authorization: Bearer sk_your_secret_keyGet your API keys from Dashboard > Settings > API Keys.
Base URL
https://your-deployment.convex.site/api/v1This is the Convex HTTP endpoint for your deployment. Replace your-deployment with your actual Convex deployment URL.
Endpoints
Feedback
GET /api/v1/feedback
List all feedback for an organization.
Query parameters
| Parameter | Type | Description |
|---|---|---|
publicKey | string | Required. Your public API key. |
status | string | Filter by status (e.g. open, in_progress, closed). |
sort | string | Sort order: votes, newest, or oldest. |
limit | number | Number of items to return (default 20). |
cursor | string | Pagination cursor from a previous response. |
Example request
curl "https://your-deployment.convex.site/api/v1/feedback?publicKey=pk_xxx&sort=votes&limit=10"Example response
{
"feedback": [
{
"id": "fb_abc123",
"title": "Add dark mode",
"description": "Please add a dark mode option.",
"status": "open",
"voteCount": 42,
"commentCount": 5,
"createdAt": "2026-01-15T10:30:00Z"
}
],
"config": {
"statuses": ["open", "in_progress", "completed", "closed"],
"tags": ["feature", "bug", "improvement"]
},
"nextCursor": "eyJpZCI6ImZiX2RlZjQ1NiJ9"
}POST /api/v1/feedback
Create new feedback. Requires a secret key or user token.
Request body
{
"title": "Add dark mode",
"description": "It would be great to have a dark mode option.",
"tagId": "tag_feature"
}Example request
curl -X POST "https://your-deployment.convex.site/api/v1/feedback" \
-H "Authorization: Bearer sk_xxx" \
-H "Content-Type: application/json" \
-d '{"title": "Add dark mode", "description": "Please add a dark mode option."}'Example response
{
"id": "fb_abc123",
"title": "Add dark mode",
"description": "Please add a dark mode option.",
"status": "open",
"voteCount": 0,
"commentCount": 0,
"createdAt": "2026-02-24T12:00:00Z"
}GET /api/v1/feedback/:id
Get a single feedback item by ID. Returns the feedback object with vote count, comments count, and status.
Example request
curl "https://your-deployment.convex.site/api/v1/feedback/fb_abc123?publicKey=pk_xxx"Example response
{
"id": "fb_abc123",
"title": "Add dark mode",
"description": "Please add a dark mode option.",
"status": "open",
"voteCount": 42,
"commentCount": 5,
"tagId": "tag_feature",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-02-20T08:15:00Z"
}POST /api/v1/feedback/:id/vote
Vote on a feedback item.
Request body
{
"feedbackId": "fb_abc123",
"voteType": "upvote"
}Example request
curl -X POST "https://your-deployment.convex.site/api/v1/feedback/fb_abc123/vote" \
-H "Authorization: Bearer sk_xxx" \
-H "Content-Type: application/json" \
-d '{"feedbackId": "fb_abc123", "voteType": "upvote"}'The voteType field accepts upvote or downvote.
GET /api/v1/feedback/:id/comments
Get comments for a feedback item. Returns an array of comments with nested replies.
Example request
curl "https://your-deployment.convex.site/api/v1/feedback/fb_abc123/comments?publicKey=pk_xxx"Example response
{
"comments": [
{
"id": "cmt_001",
"body": "This would be amazing!",
"authorName": "Jane Doe",
"createdAt": "2026-01-16T09:00:00Z",
"replies": [
{
"id": "cmt_002",
"body": "Agreed, especially for late-night use.",
"authorName": "John Smith",
"parentId": "cmt_001",
"createdAt": "2026-01-16T10:30:00Z"
}
]
}
]
}POST /api/v1/feedback/:id/comments
Add a comment to a feedback item. Optionally include a parentId to create a reply.
Request body
{
"feedbackId": "fb_abc123",
"body": "Great idea, would love this feature!",
"parentId": "cmt_001"
}Example request
curl -X POST "https://your-deployment.convex.site/api/v1/feedback/fb_abc123/comments" \
-H "Authorization: Bearer sk_xxx" \
-H "Content-Type: application/json" \
-d '{"feedbackId": "fb_abc123", "body": "Great idea!"}'Example response
{
"id": "cmt_003",
"body": "Great idea!",
"authorName": "You",
"feedbackId": "fb_abc123",
"createdAt": "2026-02-24T12:00:00Z"
}Changelog
GET /api/v1/changelog
Get published changelog entries for an organization.
Example request
curl "https://your-deployment.convex.site/api/v1/changelog?publicKey=pk_xxx"Example response
{
"entries": [
{
"id": "cl_001",
"title": "Dark mode is here",
"body": "We shipped dark mode across the entire app...",
"publishedAt": "2026-02-20T14:00:00Z",
"tags": ["feature", "ui"]
}
]
}Roadmap
GET /api/v1/roadmap
Get public roadmap milestones for an organization.
Example request
curl "https://your-deployment.convex.site/api/v1/roadmap?publicKey=pk_xxx"Example response
{
"milestones": [
{
"id": "ms_001",
"title": "Q1 2026",
"description": "First quarter priorities",
"status": "in_progress",
"items": [
{
"id": "fb_abc123",
"title": "Add dark mode",
"status": "completed"
},
{
"id": "fb_def456",
"title": "API webhooks",
"status": "in_progress"
}
]
}
]
}Subscriptions
POST /api/v1/subscribe
Subscribe an email address to changelog updates.
Request body
{
"email": "user@example.com"
}Example request
curl -X POST "https://your-deployment.convex.site/api/v1/subscribe" \
-H "Authorization: Bearer sk_xxx" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'Example response
{
"subscribed": true,
"email": "user@example.com"
}Rate Limiting
API requests are rate limited per API key. When you exceed the limit, requests will return a 429 status code. Check the response headers to monitor your usage.
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed per window. |
X-RateLimit-Remaining | Number of requests remaining in the current window. |
Errors
All error responses follow a consistent JSON format with an error field describing the issue.
{
"error": "Error message description"
}| Status Code | Meaning | Description |
|---|---|---|
400 | Bad Request | The request body or parameters are invalid. |
401 | Unauthorized | Missing or invalid API key. |
404 | Not Found | The requested resource does not exist. |
429 | Rate Limited | Too many requests. Wait and retry after the rate limit window resets. |