Scoped keys
Grant only the read or write scopes an integration needs.
REST management API · v1
Manage projects, requests, comments, releases, and usage from server-side tools. The API uses JSON, scoped project keys, cursor pagination, and predictable error envelopes.
Grant only the read or write scopes an integration needs.
Standard limits are 100 requests per minute per key.
Private actor traits and subscriber addresses are never returned.
curl https://priosmith.com/api/v1/projects \
-H "Authorization: Bearer ps_live_your_key" \
-H "Accept: application/json"Send a project-bound API key as a Bearer token. Keys are shown once when created, then stored only as a purpose-separated HMAC digest. Rotate a key immediately if it is exposed.
Authorization: Bearer ps_live_your_key| Scope | Allows |
|---|---|
| projects:read | List accessible projects and configuration |
| features:read / features:write | Read or manage requests and moderation status |
| comments:read / comments:write | Read or add administrative comments |
| releases:read / releases:write | Read releases and create drafts |
| releases:publish | Publish a release and enqueue subscriber notifications |
| usage:read | Read aggregate project usage |
6 of 35 endpoints
Clear endpoint filters| Method | Path | Purpose | MCP tool |
|---|---|---|---|
| GET | /api/v1/projects | List projects available to the project-bound API key. | list_projects |
| GET | /api/v1/projects/:projectId/features | List and cursor-page feature requests. | list_features |
| GET | /api/v1/projects/:projectId/features/:featureId | Read one feature request. | get_feature |
| GET | /api/v1/projects/:projectId/features/:featureId/comments | List non-deleted comments with moderation state. | list_comments |
| GET | /api/v1/projects/:projectId/releases | List draft, scheduled, and published releases. | list_releases |
| GET | /api/v1/projects/:projectId/usage | Return project counters and plan usage. | project_usage |
Open an endpoint only when you need its complete example. Copying the documentation includes every matching collapsed example.
Request
GET /api/v1/projects
Authorization: Bearer ps_live_your_key
Accept: application/jsonSuccess response
200 OK
{
"data": {
"projects": [
{
"id": "3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2",
"name": "Northstar",
"slug": "northstar",
"description": "Customer feedback for the Northstar product.",
"visibility": "public",
"published_at": "2026-07-13T12:00:00.000Z",
"archived_at": null,
"created_at": "2026-07-13T12:00:00.000Z",
"updated_at": "2026-07-13T12:00:00.000Z"
}
]
}
}Request
GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/features?limit=50&cursor=NEXT_CURSOR
Authorization: Bearer ps_live_your_key
Accept: application/jsonSuccess response
200 OK
{
"data": {
"features": [
{
"id": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
"request_number": 42,
"project_id": "3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2",
"status_id": "97a8ad23-f482-49bb-88b9-716c5f41709d",
"title": "Native mobile app",
"slug": "native-mobile-app",
"body": "iOS and Android access for field teams",
"post_type": "feature",
"moderation_state": "visible",
"is_pinned": false,
"notify_followers": true,
"vote_count": 18,
"comment_count": 3,
"subscriber_count": 12,
"target_date": "2026-10-15",
"published_at": "2026-07-13T12:00:00.000Z",
"released_at": null,
"created_at": "2026-07-13T12:00:00.000Z",
"updated_at": "2026-07-13T12:00:00.000Z"
}
],
"nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LS4uLiJ9"
}
}Request
GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/features/f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f
Authorization: Bearer ps_live_your_key
Accept: application/jsonSuccess response
200 OK
{
"data": {
"feature": {
"id": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
"request_number": 42,
"project_id": "3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2",
"status_id": "97a8ad23-f482-49bb-88b9-716c5f41709d",
"title": "Native mobile app",
"slug": "native-mobile-app",
"body": "iOS and Android access for field teams",
"post_type": "feature",
"moderation_state": "visible",
"is_pinned": false,
"notify_followers": true,
"vote_count": 18,
"comment_count": 3,
"subscriber_count": 12,
"target_date": "2026-10-15",
"published_at": "2026-07-13T12:00:00.000Z",
"released_at": null,
"created_at": "2026-07-13T12:00:00.000Z",
"updated_at": "2026-07-13T12:00:00.000Z"
}
}
}Request
GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/features/f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f/comments?limit=50
Authorization: Bearer ps_live_your_key
Accept: application/jsonSuccess response
200 OK
{
"data": {
"comments": [
{
"id": "25bb8fa2-1eec-47a5-9f45-4400dcc9e816",
"project_id": "3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2",
"post_id": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
"parent_comment_id": null,
"body": "We have started the technical design.",
"is_internal": false,
"moderation_state": "visible",
"edited_at": null,
"created_at": "2026-07-13T12:00:00.000Z",
"updated_at": "2026-07-13T12:00:00.000Z"
}
],
"nextCursor": null
}
}Request
GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/releases?limit=50
Authorization: Bearer ps_live_your_key
Accept: application/jsonSuccess response
200 OK
{
"data": {
"releases": [
{
"id": "b6f1472f-2fc3-4dd9-b06e-c8931ae245f7",
"project_id": "3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2",
"title": "Mobile beta",
"slug": "mobile-beta",
"summary": "The private beta is ready.",
"body": "Invitations are rolling out to the first customer cohort.",
"status": "draft",
"scheduled_at": null,
"published_at": null,
"created_at": "2026-07-13T12:00:00.000Z",
"updated_at": "2026-07-13T12:00:00.000Z"
}
],
"nextCursor": null
}
}Request
GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/usage
Authorization: Bearer ps_live_your_key
Accept: application/jsonSuccess response
200 OK
{
"data": {
"projectId": "3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2",
"counts": {
"features": 42,
"votes": 318,
"comments": 67,
"releases": 8,
"activeSubscribers": 96
},
"calculatedAt": "2026-07-13T12:00:00.000Z"
}
}Collection endpoints return a stable opaque cursor. Pass the previous response's nextCursor value in the next request. The default page size is 50 and the maximum is 100.
GET /api/v1/projects/PROJECT_ID/features?limit=50&cursor=NEXT_CURSOR
{
"data": {
"features": [...],
"nextCursor": "opaque-value"
}
}Keys allow 100 requests per minute. Write endpoints also apply a limit of 10 requests per two minutes per key. Counters are coordinated in Supabase across Vercel instances. Every response includes limit, remaining, and reset headers. A 429 response includes Retry-After.
RateLimit-Limit: 100
RateLimit-Remaining: 97
RateLimit-Reset: 1752339660Webhook payloads are signed with HMAC-SHA256. Verify the raw request body before parsing JSON, reject stale timestamps, and make event processing idempotent by event ID.
X-PrioSmith-Signature: t=1752339600,v1=hex_digest
X-PrioSmith-Event: feature.status_changed
X-PrioSmith-Delivery: 019f...
{
"apiVersion": "2026-07-13",
"id": "019f...",
"type": "feature.status_changed",
"createdAt": "2026-07-13T12:00:00.000Z",
"workspaceId": "WORKSPACE_ID",
"projectId": "PROJECT_ID",
"data": { "objectType": "feature", "objectId": "FEATURE_ID" }
}Connect an MCP client to https://priosmith.com/api/mcp and send the same scoped API key as a Bearer token. The server supports initialization, ping, tool discovery, all twelve canonical management operations, and twenty-three collision-safe compatibility_ tools for the directly evidenced feature, voter, comment, release, project, usage, and changelog-generation operations above. Compatibility tools inherit the key's project boundary and do not accept a project override. Only tools allowed by every required key scope are advertised.
{
"mcpServers": {
"priosmith": {
"url": "https://priosmith.com/api/mcp",
"headers": {
"Authorization": "Bearer ps_live_your_key"
}
}
}
}The transport uses JSON responses without server-managed sessions or SSE. Never put an API key in browser code, a public repository, or a URL.
The repository includes the original-branded @priosmith/mcp-server package source. It forwards newline-delimited JSON-RPC from stdio to the same scoped /api/mcp service without printing credentials.
{
"mcpServers": {
"priosmith": {
"command": "node",
"args": [
"/absolute/path/to/priosmith/packages/priosmith-mcp/bin/priosmith-mcp.mjs"
],
"env": {
"PRIOSMITH_API_KEY": "ps_live_your_key",
"PRIOSMITH_API_URL": "https://priosmith.com/api/mcp"
}
}
}
}npx @priosmith/mcp-server until an owner publishes and verifies the package on npm.Errors use stable machine-readable codes. A request ID is safe to share with support; raw payloads, credentials, and customer PII are never included.
{
"error": {
"code": "BAD_REQUEST",
"message": "The request is invalid.",
"requestId": "req_019f..."
}
}