REST API
Patchrooms has a small REST API for reading and updating the data behind a single project — projects, feedback reports, and channels. It is intentionally minimal: most teams pull feedback through the MCP endpoint or the dashboard, and use this API only for custom integrations.
Base URL and auth
Section titled “Base URL and auth”https://room.patchrooms.com/api/v1Every route lives under a project and is authenticated with a secret API key
(prefix pr_sk_) created in the dashboard, sent as a Bearer token bound to that
project:
Authorization: Bearer pr_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxEach endpoint requires a specific scope (listed below). A missing or revoked key
returns 401; a key without the required scope returns 403.
In the paths below, :projectId is the project’s internal id (a MongoDB
ObjectId), not the public pr_ project key.
Projects
Section titled “Projects”Get a project
Section titled “Get a project”GET /api/v1/projects/:projectIdScope: project:read. Returns the project’s name, public key, URL patterns,
default channel, and whether an identity secret is set.
{ "id": "665e...", "name": "Acme App", "projectKey": "pr_xxx", "urlPatterns": ["https://app.acme.com/*"], "defaultChannelKey": "bug", "identitySecretSet": false, "createdAt": "2026-05-01T12:00:00.000Z"}Feedback
Section titled “Feedback”List reports
Section titled “List reports”GET /api/v1/projects/:projectId/feedbackScope: feedback:read. Returns reports newest first with cursor pagination.
| Query param | Type | Description |
|---|---|---|
limit | number | Page size. Defaults to 20, capped at 100. |
channelKey | string | Filter by channel key. |
status | string | Filter by report status. |
before | string | Cursor — a report id; returns reports older than it. |
{ "items": [ { "id": "665f...", "channelKey": "bug", "status": "open", "blocks": [ /* Block[] */ ], "context": { /* ... */ }, "identity": null, "createdAt": "2026-06-03T09:14:22.000Z" } ], "nextCursor": "665e..."}Pass nextCursor back as the before query param to fetch the next page.
nextCursor is null on the last page.
Get a report
Section titled “Get a report”GET /api/v1/projects/:projectId/feedback/:reportIdScope: feedback:read. Returns one report with its full blocks, context,
and identity. Returns 404 if the report is not found in this project.
Update report status
Section titled “Update report status”PATCH /api/v1/projects/:projectId/feedback/:reportIdScope: feedback:write. Body: { "status": "<status>" }. An invalid status
returns 400.
{ "id": "665f...", "status": "resolved" }Channels
Section titled “Channels”List channels
Section titled “List channels”GET /api/v1/projects/:projectId/channelsScope: channel:read. Returns the project’s channels. Pass ?archived=true to
include archived channels.
{ "items": [ { "id": "665d...", "key": "bug", "name": "Bug", "color": "#c0392b", "mascot": "fox", "baseWeight": 1, "archived": false } ]}Create a channel
Section titled “Create a channel”POST /api/v1/projects/:projectId/channelsScope: channel:write. Creates a channel from the request body. A duplicate
key in the same project returns 409; invalid input returns 400.
Update a channel
Section titled “Update a channel”PATCH /api/v1/projects/:projectId/channels/:channelKeyScope: channel:write. Updates the matching channel. Returns 404 if no
channel with that key exists in the project.
Add a channel hint
Section titled “Add a channel hint”POST /api/v1/projects/:projectId/hintsScope: channel:write. Records a short-lived hint that biases channel matching
toward a channel (it expires after 5 minutes).
| Body field | Type | Description |
|---|---|---|
channelKey | string | Channel to bias toward. Required. |
weight | 'suggest' | 'max' | number | Strength of the hint. Required. |
userId | string | Optional user this hint applies to. |
{ "ok": true }Errors
Section titled “Errors”Errors are returned as JSON with an error message and a code:
{ "error": "Not found", "code": "NOT_FOUND" }| HTTP | code | Meaning |
|---|---|---|
400 | BAD_REQUEST | Invalid input. |
401 | UNAUTHORIZED | Missing, invalid, or revoked API key. |
403 | FORBIDDEN | Key lacks the required scope. |
404 | NOT_FOUND | Resource not found in this project. |
409 | CONFLICT | Channel key already exists. |