ProductOSDocs

Entity reference · v1

outcomes

OUTC-NNNNNNtable outcomessoft delete

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

LinkWhere it livesUse it for
Initiativethe initiative_id fieldThe bet this outcome measures. One per outcome. The outcome reaches that initiative's features and releases through it.
Releasethe release_id fieldThe release the measurement starts from. One per outcome.
Featuresthe features junction (outcome_features)The specific features that are meant to move the metric. Many to many, and independent of the initiative.
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 daily series, and suggestion, the result the metrics point to (hit, mixed, missed or null) with its reason. ?include_series=false leaves the series out
  • POST /api/v1/outcomes/{id}/metrics: add one. Send role (primary, guardrail or supporting), name, direction (increase or decrease: which way is good), an optional target, and source: manual with baseline and actual, or amplitude with event (a name from the project's event list), kind (event_count or unique_users) and the windows baseline_days and measure_days (default 28). A measured metric is fetched at once. Returns 201
  • GET /api/v1/outcomes/{id}/metrics/{metricId}: one metric
  • PATCH /api/v1/outcomes/{id}/metrics/{metricId}: send only the fields that change. Changing what a measured metric counts (source, event, kind or a window) deletes its history and fetches it again
  • DELETE /api/v1/outcomes/{id}/metrics/{metricId}: remove it and its history
  • POST /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

GET/api/v1/outcomes
POST/api/v1/outcomes
GET/api/v1/outcomes/{id}
PATCH/api/v1/outcomes/{id}
DELETE/api/v1/outcomes/{id}
POST/api/v1/outcomes/{id}/restore
GET/api/v1/outcomes/{id}/links/features
POST/api/v1/outcomes/{id}/links/features
DELETE/api/v1/outcomes/{id}/links/features/{targetId}

Writable fields

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

FieldTypeConstraintsNotes
initiative*string
initiative_iduuid
release_iduuid
metric*json
resultstringhit | missed | mixed | pending
review_due_datedate
released_datedate
learningtext
ai_learningtext
next_actiontext
amplitude_linkstring
is_draftboolean
metadatajson

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

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

Try it out

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

GET/api/v1/outcomes?limit=3

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