ProductOSDocs

Entity reference · v1

deal-blockers

DEAL-NNNNNNtable deal_blockerssoft delete

Deals blocked by missing features or capabilities.

A deal blocker is a deal stuck behind something product has not built: the revenue-quantified input from sales into prioritization. Each row carries the account, the features it is waiting on, a revenue_impact and a status of open, resolved or lost.

One account, many features

The two links on a blocker are deliberately different shapes, because the relationships are different.

account_id is a column. A blocker is about one deal at one account, so the reference lives on the row and you set it like any other field.

Features go through the deal_blocker_features junction, reached at /api/v1/deal-blockers/{id}/links/features. A deal is routinely stuck on more than one missing capability, and a single column would force one row per feature and split one deal's revenue_impact across duplicates.

Linking

POST   /api/v1/deal-blockers/{id}/links/features      { "ids": ["<feature uuid>", ...] }
DELETE /api/v1/deal-blockers/{id}/links/features/{targetId}

The reverse is available on the feature, which is how you answer "which deals are blocked on this?":

GET /api/v1/features/{id}/links/deal-blockers

Both accept a UUID or a sequence id (DEAL-000089, FEAT-004082) in the path.

Tenancy

A blocker can only link a feature in its own workspace; cross-workspace ids are rejected.

workspace_id is set from the blocker; callers never supply it. Deleting a blocker cascades its links.

The AI grounding that ProductSense and Copilot read (the workspace knowledge block and each feature's entity context) carries every feature's blockers with their revenue_impact, read through the junction, so a blocker waiting on three features contributes to all three. The Sales Canvas totals revenue at risk the same way. The Features page does not show blockers.

Import and export

The workbook's Deal Blockers sheet carries a Features column of semicolon-separated feature titles, matching every other multi-link column. Import also accepts a singular Feature header from older exports.

Endpoints

GET/api/v1/deal-blockers
POST/api/v1/deal-blockers
GET/api/v1/deal-blockers/{id}
PATCH/api/v1/deal-blockers/{id}
DELETE/api/v1/deal-blockers/{id}
POST/api/v1/deal-blockers/{id}/restore
GET/api/v1/deal-blockers/{id}/links/features
POST/api/v1/deal-blockers/{id}/links/features
DELETE/api/v1/deal-blockers/{id}/links/features/{targetId}

Writable fields

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

FieldTypeConstraintsNotes
titlestring
account_iduuid
descriptiontext
revenue_impactfloat
statusstringopen | resolved | lost
prioritystringcritical | high | medium | low
resolution_notestext
is_draftboolean
metadatajson

Listing & filtering

  • Pagination: ?limit=50&offset=0 · max limit 200
  • Default sort: ?sort=revenue_impact&order=desc
  • Sortable fields: created_at · updated_at · revenue_impact · id_number
  • Search (?q=): title, description, resolution_notes
  • Filters: ?status= ?priority= ?account_id= , repeat any filter to OR multiple values
  • Trash: hidden by default; pass ?include_deleted=true
  • Expand: ?expand=features

Examples

curlbash
curl 'https://productos.ca/api/v1/deal-blockers?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/deal-blockers. 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/deal-blockers?limit=3

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