Skip to content
Browse this documentation8 sections

REST management API · v1

Build customer feedback into your workflow.

Manage projects, requests, comments, releases, and usage from server-side tools. The API uses JSON, scoped project keys, cursor pagination, and predictable error envelopes.

Plain text, including 6 matching endpoints and examples below.
Admin use only — not for public-facing UIs. API keys grant management privileges. Never expose one in client-side code, browser storage, a public website, or a URL.

Scoped keys

Grant only the read or write scopes an integration needs.

Rate limited

Standard limits are 100 requests per minute per key.

Privacy safe

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"
01

Authentication

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
ScopeAllows
projects:readList accessible projects and configuration
features:read / features:writeRead or manage requests and moderation status
comments:read / comments:writeRead or add administrative comments
releases:read / releases:writeRead releases and create drafts
releases:publishPublish a release and enqueue subscriber notifications
usage:readRead aggregate project usage
02

Endpoints

Compatibility privacy differences. Source-compatible voter reads return safe labels and masked email only. Adding a voter queues a confirmation invitation and does not create a vote or consent until the recipient confirms. Author identity fields and caller-supplied project IDs are rejected.

6 of 35 endpoints

Clear endpoint filters
MethodPathPurposeMCP tool
GET/api/v1/projectsList projects available to the project-bound API key.list_projects
GET/api/v1/projects/:projectId/featuresList and cursor-page feature requests.list_features
GET/api/v1/projects/:projectId/features/:featureIdRead one feature request.get_feature
GET/api/v1/projects/:projectId/features/:featureId/commentsList non-deleted comments with moderation state.list_comments
GET/api/v1/projects/:projectId/releasesList draft, scheduled, and published releases.list_releases
GET/api/v1/projects/:projectId/usageReturn project counters and plan usage.project_usage

Request and response examples

Open an endpoint only when you need its complete example. Copying the documentation includes every matching collapsed example.

GET/api/v1/projectsprojects:read

Request

GET /api/v1/projects
Authorization: Bearer ps_live_your_key
Accept: application/json

Success 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"
      }
    ]
  }
}
GET/api/v1/projects/:projectId/featuresfeatures:read

Request

GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/features?limit=50&cursor=NEXT_CURSOR
Authorization: Bearer ps_live_your_key
Accept: application/json

Success 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"
  }
}
GET/api/v1/projects/:projectId/features/:featureIdfeatures:read

Request

GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/features/f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f
Authorization: Bearer ps_live_your_key
Accept: application/json

Success 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"
    }
  }
}
GET/api/v1/projects/:projectId/features/:featureId/commentscomments:read

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/json

Success 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
  }
}
GET/api/v1/projects/:projectId/releasesreleases:read

Request

GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/releases?limit=50
Authorization: Bearer ps_live_your_key
Accept: application/json

Success 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
  }
}
GET/api/v1/projects/:projectId/usageusage:read

Request

GET /api/v1/projects/3fc4d742-57ef-4d41-b22e-c0bdb43a0fd2/usage
Authorization: Bearer ps_live_your_key
Accept: application/json

Success 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"
  }
}
03

Pagination

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"
  }
}
04

Rate limits

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: 1752339660
05

Signed webhooks

Webhook 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.

feature.createdfeature.upvotedcomment.createdfeature.status_changedrelease.published
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" }
}
06

MCP integrations

Streamable HTTP

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.

Stdio package

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"
      }
    }
  }
}
Registry publication is not verified. The package can be run from this checkout. Do not use npx @priosmith/mcp-server until an owner publishes and verifies the package on npm.
07

Errors

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..."
  }
}