ProductOSDocs

Entity reference · v1

feedback

FDBK-NNNNNNtable feedbacksoft delete

User-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 critical urgency feedback might still be low priority 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=...:

JunctionLinks toCarries extra fields
themesthemes entityconfidence (0 to 1, AI-assigned)
featuresfeatures entity–
personaspersonas entity–
accountsaccounts 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"]
  }'
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

GET/api/v1/feedback
POST/api/v1/feedback
GET/api/v1/feedback/{id}
PATCH/api/v1/feedback/{id}
DELETE/api/v1/feedback/{id}
POST/api/v1/feedback/{id}/restore
GET/api/v1/feedback/{id}/links/themes
POST/api/v1/feedback/{id}/links/themes
DELETE/api/v1/feedback/{id}/links/themes/{targetId}
GET/api/v1/feedback/{id}/links/features
POST/api/v1/feedback/{id}/links/features
DELETE/api/v1/feedback/{id}/links/features/{targetId}
GET/api/v1/feedback/{id}/links/personas
POST/api/v1/feedback/{id}/links/personas
DELETE/api/v1/feedback/{id}/links/personas/{targetId}
GET/api/v1/feedback/{id}/links/accounts
POST/api/v1/feedback/{id}/links/accounts
DELETE/api/v1/feedback/{id}/links/accounts/{targetId}

Writable fields

* required on create. PATCH treats every field as optional.

FieldTypeConstraintsNotes
title*string
descriptiontext
sourcestringWidget | Intercom | Slack | Zendesk | Email | Manual | Client Feedback | Internal | Notion | Jira | GitHub | Salesforce | HubSpot | Linear | Confluence | CSV | API | G2 | Social Media | In-App | Meeting
segmentstring
statusstringnew | under-review | planned | in-progress | addressed | declined | wont-do
urgencystringcritical | high | medium | low
votesinteger≥ 0
tagsstring[]
product_iduuid
module_iduuid
is_draftboolean
metadatajson

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

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

Try it out

Issue tokens in Settings → API tokens. Token never leaves this page.

GET/api/v1/feedback?limit=3

Generated from the API's entity configuration. This page is rebuilt on every deploy, so it always matches the live API.