Feature requests (REST)
Feature requests are Customer Portal records shared with the SDK request board. Four API surfaces serve different callers:
- Dashboard —
/v1/apps/:appId/requests/*— WorkOS-authenticated list, triage, moderation, and developer responses. - SDK —
/v1/sdk/requests/*— write key plus subject token; every identity is checked against the authenticated anonymous or identified subject. - Earlier public roadmap —
/v1/public/roadmap/*— read-only request routes configured by the earlier roadmap settings. - Customer Portal —
/v1/portal/:portalSlug/apps/:appSlug/*— published request reads and email-verified visitor submission/voting. See Customer Portal API.
Team-created roadmap items, help articles, collections, and release notes use the separate Portal content API. A team roadmap item is not a feature request.
List requests (admin)
GET /v1/apps/:appId/requests?status=planned&q=dark+mode&sort=topThe response is an array of request summaries in the standard data envelope.
Dashboard list filters include status, q, sort, filter, hidden, and
limit.
Create (SDK)
POST /v1/sdk/requests
Authorization: Bearer rk_live_…
X-UserGist-Subject-Token: st_…
Content-Type: application/json
{
"anonymousId": "device_a1b2c3",
"externalId": "user_42",
"idempotencyKey": "d0948d6e-65d2-4db1-9dba-e46670a4d8ef",
"title": "Dark mode for the dashboard",
"description": "Eye-strain on long sessions — would love a system-aware toggle."
}externalId is optional for anonymous users. If supplied, it must match the
identified subject token. Feedback consent is required.
Update status
PATCH /v1/apps/:appId/requests/:requestId/status
{ "status": "in_progress" }Valid statuses: under_review, planned, in_progress, shipped, declined.
Changing status applies the configured follower rules and queues eligible in-app SDK instructions. Automatic native push for request updates is not implemented. A status change does not change portal visibility or publish a changelog entry.
Vote / un-vote (SDK)
POST /v1/sdk/requests/:requestId/vote
{ "anonymousId": "device_a1b2c3", "externalId": "user_42", "vote": true }Send vote: false to remove the vote. Voting auto-follows; un-voting does not
unfollow.
Follow / unfollow (SDK)
POST /v1/sdk/requests/:requestId/follow
{ "anonymousId": "device_a1b2c3", "externalId": "user_42", "follow": true }Send follow: false to unfollow.
Comments
GET /v1/sdk/requests/:requestId/comments
POST /v1/sdk/requests/:requestId/comments
PATCH /v1/sdk/requests/:requestId/comments/:commentId
DELETE /v1/sdk/requests/:requestId/comments/:commentId?anonymousId=device_a1b2c3SDK comment calls require the write key, subject token, and matching identity.
Create also requires an idempotencyKey. The original anonymous identity can
edit or delete its comment. Dashboard viewers can read comments at
GET /v1/apps/:appId/requests/:requestId/comments; editors can remove a comment
at DELETE /v1/apps/:appId/requests/:requestId/comments/:commentId.
Earlier public-roadmap reads
GET /v1/public/roadmap/:slug
GET /v1/public/roadmap/:slug/r/:requestId
GET /v1/public/roadmap/:slug/brandingNo authentication. These routes depend on the earlier publicRoadmapEnabled and publicSlug request settings; they do not represent the complete company portal. For the current hosted portal, use the public routes in Customer Portal API.
Current portal visibility
Editors or higher use PATCH /v1/apps/:appId/requests/portal-visibility with { ids: [UUID], visible: true | false }, up to 100 requests per call. Global hiding overrides portal visibility. Removing a request from the portal does not remove it from the SDK board.
Public portal reads expose title, description, status, votes, and the team response, rather than private SDK comments or participant identities. Portal visitor tokens cannot call SDK comment or follow routes.