Entity reference · v1
feedback
FDBK-NNNNNNtable feedbacksoft deleteUser-submitted feedback. Soft-deleted via deleted_at; recoverable via /restore.
The feedback entity is the upstream of the Golden Thread. Every analysis, summary, and outcome in ProductOS eventually traces back to a row in this table.
This page is the narrative companion to the auto-generated reference below: endpoints, fields, and junctions are listed automatically from the API's entity configuration. Use this section for the why and the gotchas.
When to create feedback
Create a feedback row whenever a user voice arrives that you might one day want to count, tag, or roll up into a theme. The bar should be low, better to over-capture than to lose the signal.
Common sources:
- Support ticket replies (Intercom, Zendesk, Freshdesk)
- Sales call clips (Gong, Granola, manual)
- In-app widget submissions (
/api/v1/public/widget/feedback) - Your own product, through the Feedback API (
/api/v1/public/feedback,source = API) - Excel workbook imports from past systems
- Direct API posts from automations
Urgency vs. priority
Feedback has an urgency field, how blocking is this for the reporter?, that's distinct from a feature's priority field, how scheduled is this for the team?
- A
criticalurgency feedback might still belowpriority if the workspace has 200 other critical-urgency reports that didn't move the team. - Urgency is set by support / the customer; priority is set by the PM / engineering planning.
Keep them separate or your scoring breaks.
Junctions
Feedback has four junctions, all expandable via ?expand=...:
| Junction | Links to | Carries extra fields |
|---|---|---|
themes | themes entity | confidence (0 to 1, AI-assigned) |
features | features entity | – |
personas | personas entity | – |
accounts | accounts entity | – |
The confidence field on themes (0 to 1) is how the auto-clustering AI records how sure it was about a match; set it yourself when you link programmatically so the origin of the link stays legible. Pass it as fields on the link (extra is the older name for the same object). A value outside 0 to 1, or any field on a junction that has none, is refused with a 422, and the MCP link_entities action takes the same fields.
Soft delete + restore
Deletes are soft by default. A DELETE /api/v1/feedback/{id} sets deleted_at and removes the row from list responses, but the row stays in the table. Pass ?hard=true to permanently delete, or POST /api/v1/feedback/{id}/restore to bring a soft-deleted row back.
Sequence IDs (FDBK-NNNNNN) are preserved across soft delete + restore. They are not reused if a row is hard-deleted.
Pagination on big workspaces
The list endpoint caps limit at 200. On workspaces with 100k+ feedback rows, paginate using offset only up to ~10k, beyond that, server-side LIMIT/OFFSET gets slow. For full exports use GET /api/v1/feedback/export?format=json|csv, which returns every row in one response (see Pagination).
Common patterns
Pull the highest-voted unaddressed feedback for a triage queue
curl 'https://productos.ca/api/v1/feedback?status=new&status=under-review&sort=votes&order=desc&limit=50' \
-H "Authorization: Bearer $TOKEN"Create a feedback item from an external integration
curl 'https://productos.ca/api/v1/feedback' \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Wants to import roadmaps from Productboard",
"description": "Customer migrating off Productboard…",
"source": "Intercom",
"urgency": "medium",
"tags": ["migration", "competitive"]
}'Link a feedback item to a theme
curl 'https://productos.ca/api/v1/feedback/FDBK-000042/links/themes' \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "ids": ["THM-000007"], "fields": { "confidence": 0.92 } }'The auto-generated endpoint, field, and filter reference is rendered below.
Endpoints
/api/v1/feedback/api/v1/feedback/api/v1/feedback/{id}/api/v1/feedback/{id}/api/v1/feedback/{id}/api/v1/feedback/{id}/restore/api/v1/feedback/{id}/links/themes/api/v1/feedback/{id}/links/themes/api/v1/feedback/{id}/links/themes/{targetId}/api/v1/feedback/{id}/links/features/api/v1/feedback/{id}/links/features/api/v1/feedback/{id}/links/features/{targetId}/api/v1/feedback/{id}/links/personas/api/v1/feedback/{id}/links/personas/api/v1/feedback/{id}/links/personas/{targetId}/api/v1/feedback/{id}/links/accounts/api/v1/feedback/{id}/links/accounts/api/v1/feedback/{id}/links/accounts/{targetId}Writable fields
* required on create. PATCH treats every field as optional.
| Field | Type | Constraints | Notes |
|---|---|---|---|
| title* | string | ||
| description | text | ||
| source | string | Widget | Intercom | Slack | Zendesk | Email | Manual | Client Feedback | Internal | Notion | Jira | GitHub | Salesforce | HubSpot | Linear | Confluence | CSV | API | G2 | Social Media | In-App | Meeting | |
| segment | string | ||
| status | string | new | under-review | planned | in-progress | addressed | declined | wont-do | |
| urgency | string | critical | high | medium | low | |
| votes | integer | ≥ 0 | |
| tags | string[] | ||
| product_id | uuid | ||
| module_id | uuid | ||
| is_draft | boolean | ||
| metadata | json |
Listing & filtering
- Pagination:
?limit=50&offset=0· max limit 200 - Default sort:
?sort=votes&order=desc - Sortable fields: created_at · updated_at · votes · urgency · title · id_number
- Search (?q=): title, description
- Filters: ?status= ?source= ?segment= ?urgency= ?product_id= ?module_id= ?is_draft= , repeat any filter to OR multiple values
- Trash: hidden by default; pass
?include_deleted=true - Expand:
?expand=themes,features
Examples
curl 'https://productos.ca/api/v1/feedback?limit=10' \
-H "Authorization: Bearer $TOKEN"Try it out
Paste a token and hit a real endpoint. The request goes from your browser straight to /api/v1/feedback. The token is held in this page only for the request and is never stored.
Issue tokens in Settings → API tokens. Token never leaves this page.
GET/api/v1/feedback?limit=3