Feature Requests API

Feature Requests API

API endpoints for creating, listing, voting on, and commenting on feature requests. All endpoints require a valid JWT token from device attestation.

FeatureStatus Enum

Feature requests progress through the following statuses:

Value Description
pendingNewly submitted, awaiting review
openReviewed and accepted for consideration
plannedScheduled for implementation
in_progressCurrently being developed
shippedReleased and available
declinedWill not be implemented
duplicateDuplicate of another request

1. List Feature Requests

GET /api/v1/feedback/features

Returns a paginated list of feature requests for the current tenant.

Query Parameters

Parameter Type Default Description
pageInt1Page number
perInt20Items per page
sortStringvotesvotes, newest, or oldest
statusStringFilter by FeatureStatus value
voterIdStringInclude hasVoted flag for this voter

Response

{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "title": "Dark mode support",
      "description": "Add a dark theme option for the app",
      "status": "open",
      "submitterId": "user_123",
      "voteCount": 42,
      "commentCount": 7,
      "hasVoted": true,
      "createdAt": "2025-01-15T10:30:00Z",
      "updatedAt": "2025-01-20T14:00:00Z"
    }
  ],
  "metadata": {
    "page": 1,
    "per": 20,
    "total": 35
  }
}

2. Get Feature Request

GET /api/v1/feedback/features/:featureId

Returns a single feature request by ID.

Response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "Dark mode support",
  "description": "Add a dark theme option for the app",
  "status": "open",
  "submitterId": "user_123",
  "voteCount": 42,
  "commentCount": 7,
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-20T14:00:00Z"
}

3. Create Feature Request

POST /api/v1/feedback/features

Creates a new feature request. The request starts in pending status.

Request Body

{
  "title": "Dark mode support",
  "description": "Add a dark theme option for the app",
  "submitterId": "user_123",
  "deviceHash": "abc123def456"
}
Field Type Required Description
titleStringYesShort title for the request
descriptionStringYesDetailed description
submitterIdStringYesYour app's user identifier
deviceHashStringNoDevice identifier from attestation

Response (201 Created)

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "Dark mode support",
  "description": "Add a dark theme option for the app",
  "status": "pending",
  "submitterId": "user_123",
  "voteCount": 0,
  "commentCount": 0,
  "createdAt": "2025-01-15T10:30:00Z"
}

4. Vote on Feature Request

POST /api/v1/feedback/features/:featureId/vote

Adds a vote to a feature request. Each voter can only vote once per feature.

Request Body

{
  "voterId": "user_123",
  "deviceHash": "abc123def456"
}

Response (200 OK)

{
  "success": true,
  "voteCount": 43
}

5. Remove Vote

DELETE /api/v1/feedback/features/:featureId/vote

Removes a previously cast vote from a feature request.

Query Parameters

Parameter Type Required Description
voterIdStringYesThe voter's identifier

Response (200 OK)

{
  "success": true,
  "voteCount": 42
}

6. List Comments

GET /api/v1/feedback/features/:featureId/comments

Returns all comments on a feature request, sorted chronologically.

Response

{
  "items": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440000",
      "authorId": "user_456",
      "authorType": "user",
      "body": "This would be great for late-night coding sessions!",
      "createdAt": "2025-01-16T09:15:00Z"
    },
    {
      "id": "770e8400-e29b-41d4-a716-446655440000",
      "authorId": "admin_1",
      "authorType": "admin",
      "body": "Thanks for the feedback! We're looking into this.",
      "createdAt": "2025-01-16T11:30:00Z"
    }
  ]
}

7. Add Comment

POST /api/v1/feedback/features/:featureId/comments

Adds a comment to a feature request.

Request Body

{
  "authorId": "user_456",
  "body": "This would be great for late-night coding sessions!"
}
Field Type Required Description
authorIdStringYesYour app's user identifier
bodyStringYesComment text content

Response (201 Created)

{
  "id": "880e8400-e29b-41d4-a716-446655440000",
  "authorId": "user_456",
  "authorType": "user",
  "body": "This would be great for late-night coding sessions!",
  "createdAt": "2025-01-16T09:15:00Z"
}

Error Responses

// 404 Not Found
{
  "error": "not_found",
  "message": "Feature request not found"
}

// 409 Conflict (duplicate vote)
{
  "error": "conflict",
  "message": "User has already voted on this feature"
}

// 403 Forbidden (tenant mismatch)
{
  "error": "forbidden",
  "message": "Access denied"
}

Next Steps