Entity reference · v1
outcomes
OUTC-NNNNNNtable outcomessoft deleteClosed-loop measurement: initiative metric (baseline → target → actual) + result.
An outcome records whether shipped work moved a metric. This page covers what the field table below can't tell you: which field names an outcome, and how it links to initiatives, releases and features.
Name and metric
An outcome has no title. Its name is the initiative field, a required string, which is what lists, pickers and search show. The field is text and is separate from initiative_id: renaming the linked initiative doesn't rename the outcome.
metric is required JSON with the keys name, baseline, target and actual. Values are stored as given, so "80%" and 80 are both accepted. actual stays null until the review is in, and result (pending, hit, missed or mixed) is set by hand.
How an outcome links to the thread
| Link | Where it lives | Use it for |
|---|---|---|
| Initiative | the initiative_id field | The bet this outcome measures. One per outcome. The outcome reaches that initiative's features and releases through it. |
| Release | the release_id field | The release the measurement starts from. One per outcome. |
| Features | the features junction (outcome_features) | The specific features that are meant to move the metric. Many to many, and independent of the initiative. |
Link a feature
curl "https://productos.ca/api/v1/outcomes/OUTC-000012/links/features" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ids": ["FEAT-000123", "FEAT-000124"]}'Linking is idempotent: posting a feature that's already linked is a no-op. Remove a link with DELETE /api/v1/outcomes/{id}/links/features/{featureId}.
An outcome can only link features from its own workspace. An id from another workspace is rejected with 404 not_found, including a bare UUID.
Which outcomes a feature moves
The same junction is exposed from the feature side:
curl "https://productos.ca/api/v1/features/FEAT-000123/links/outcomes" \
-H "Authorization: Bearer $TOKEN"In the Golden Thread walk
The walk follows all three links. From a feature it reaches the outcomes linked to it directly, and the outcomes of its initiatives and releases. From an outcome it reaches its directly linked features, then their themes and feedback.
Sub-routes
Metrics
An outcome can be judged on more than its own metric: a measured primary, guardrails that must not get worse, and supporting metrics, each typed in or measured from the workspace's analytics (Amplitude today). These routes take the in-app session, a bearer token or an API token, and accept the outcome's UUID or sequence id. Reading needs any role with access to Outcomes; writing needs member or higher. They are part of measured outcomes, a preview: while it is not turned on for your workspace they return 403.
GET /api/v1/outcomes/{id}/metrics: every metric (the measured primary first, then guardrails, then supporting), each measured one with its dailyseries, andsuggestion, the result the metrics point to (hit,mixed,missedornull) with its reason.?include_series=falseleaves the series outPOST /api/v1/outcomes/{id}/metrics: add one. Sendrole(primary,guardrailorsupporting),name,direction(increaseordecrease: which way is good), an optionaltarget, andsource:manualwithbaselineandactual, oramplitudewithevent(a name from the project's event list),kind(event_countorunique_users) and the windowsbaseline_daysandmeasure_days(default 28). A measured metric is fetched at once. Returns201GET /api/v1/outcomes/{id}/metrics/{metricId}: one metricPATCH /api/v1/outcomes/{id}/metrics/{metricId}: send only the fields that change. Changing what a measured metric counts (source,event,kindor a window) deletes its history and fetches it againDELETE /api/v1/outcomes/{id}/metrics/{metricId}: remove it and its historyPOST /api/v1/outcomes/{id}/metrics/refresh: fetch every measured metric again (6 a minute)
A measured primary writes its baseline and actual into the outcome's metric, so GET /api/v1/outcomes/{id} shows the measured numbers; a typed-in primary is the outcome's own metric and is never a row here. An outcome has at most one primary (a second is 409). A measured metric needs its provider connected in Settings, Integrations (400 otherwise). Measured numbers are the mean per day over each window. The suggestion is never applied on its own: set result with PATCH /api/v1/outcomes/{id}. Adding, changing and removing a metric are recorded on the outcome's audit trail. A bad value returns 422; an outcome outside your workspace, in the Trash, or someone else's draft returns 404.
The auto-generated endpoint, field, and junction reference is below.
Endpoints
/api/v1/outcomes/api/v1/outcomes/api/v1/outcomes/{id}/api/v1/outcomes/{id}/api/v1/outcomes/{id}/api/v1/outcomes/{id}/restore/api/v1/outcomes/{id}/links/features/api/v1/outcomes/{id}/links/features/api/v1/outcomes/{id}/links/features/{targetId}Writable fields
* required on create. PATCH treats every field as optional.
| Field | Type | Constraints | Notes |
|---|---|---|---|
| initiative* | string | ||
| initiative_id | uuid | ||
| release_id | uuid | ||
| metric* | json | ||
| result | string | hit | missed | mixed | pending | |
| review_due_date | date | ||
| released_date | date | ||
| learning | text | ||
| ai_learning | text | ||
| next_action | text | ||
| amplitude_link | string | ||
| is_draft | boolean | ||
| metadata | json |
Listing & filtering
- Pagination:
?limit=50&offset=0· max limit 200 - Default sort:
?sort=created_at&order=desc - Sortable fields: created_at · updated_at · review_due_date · released_date · id_number
- Search (?q=): initiative, learning, next_action
- Filters: ?result= ?initiative_id= ?release_id= ?is_draft= , repeat any filter to OR multiple values
- Trash: hidden by default; pass
?include_deleted=true - Expand:
?expand=features
Examples
curl 'https://productos.ca/api/v1/outcomes?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/outcomes. 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/outcomes?limit=3