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

4 of 35 endpoints

Clear endpoint filters
MethodPathPurposeMCP tool
PUT/api/featuresUpdate feature title, description, or tags transactionally.compatibility_update_feature
PUT/api/features?is_status_update=trueUpdate feature status through the notification-policy-aware transaction.compatibility_update_feature_status
PUT/api/commentsUpdate comment body or internal visibility within the key project.compatibility_update_comment
PUT/api/releasesUpdate source release fields and replace feature links within the key project. Setting is_draft to false additionally requires releases:publish.compatibility_update_release

Request and response examples

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

PUT/api/featuresCompatibility aliasfeatures:write

Request

PUT /api/features
Authorization: Bearer ps_live_your_key
Accept: application/json
Content-Type: application/json

{
  "featureId": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
  "description": "Beta access for field teams",
  "tags": [
    "Mobile",
    "Beta"
  ]
}

Success response

200 OK

{
  "data": {
    "id": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
    "title": "Native mobile app",
    "description": "iOS and Android access for field teams",
    "status": "In progress",
    "tags": [
      "Mobile"
    ],
    "votes": 18,
    "createdAt": "2026-07-13T12:00:00.000Z",
    "updatedAt": "2026-07-13T12:00:00.000Z"
  }
}
PUT/api/features?is_status_update=trueCompatibility aliasfeatures:write

Request

PUT /api/features?is_status_update=true
Authorization: Bearer ps_live_your_key
Accept: application/json
Content-Type: application/json

{
  "featureId": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
  "status": "In progress"
}

Success response

200 OK

{
  "data": {
    "id": "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f",
    "title": "Native mobile app",
    "description": "iOS and Android access for field teams",
    "status": "In progress",
    "tags": [
      "Mobile"
    ],
    "votes": 18,
    "createdAt": "2026-07-13T12:00:00.000Z",
    "updatedAt": "2026-07-13T12:00:00.000Z"
  }
}
PUT/api/commentsCompatibility aliascomments:write

Request

PUT /api/comments
Authorization: Bearer ps_live_your_key
Accept: application/json
Content-Type: application/json

{
  "commentId": "25bb8fa2-1eec-47a5-9f45-4400dcc9e816",
  "body": "Updated internal triage note",
  "is_internal": true
}

Success response

200 OK

{
  "data": {
    "id": "25bb8fa2-1eec-47a5-9f45-4400dcc9e816",
    "is_internal": true
  }
}
PUT/api/releasesCompatibility aliasreleases:write

Request

PUT /api/releases
Authorization: Bearer ps_live_your_key
Accept: application/json
Content-Type: application/json

{
  "releaseId": "b6f1472f-2fc3-4dd9-b06e-c8931ae245f7",
  "short_description": "The customer beta is ready.",
  "feature_ids": [
    "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f"
  ],
  "is_draft": false
}

Success response

200 OK

{
  "data": {
    "id": "b6f1472f-2fc3-4dd9-b06e-c8931ae245f7",
    "version": "v1.7.0",
    "title": "Mobile beta",
    "short_description": "The customer beta is ready.",
    "long_description": "Invitations are rolling out to the first customer cohort.",
    "feature_ids": [
      "f5b5c8e1-cff5-4c3f-98ec-f951dc437e2f"
    ],
    "is_draft": false,
    "created_at": "2026-07-13T12:00:00.000Z",
    "updated_at": "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..."
  }
}