Record a new outcome measurement for an intent.
Accepts a pm_live_ Bearer key with write scope OR a session cookie. The two paths differ on purpose: a key authenticates through the API-key layer, reads with the admin client, and scopes the intent lookup to the key's workspace — RLS is bypassed there, so that filter is what prevents cross-workspace writes. A session keeps the original anon+RLS client and its owner|admin|editor role gate, and needs no workspace_id query param, so the in-app caller is unaffected. Body is zod-validated (lib/outcomeMeasurementRecord.ts). met is the SERVER's conclusion, not the caller's claim: when numericValue and measurement.expectation are both present the comparator is evaluated here, met_basis is 'computed', and a contradicting caller-supplied met is discarded rather than blended. Otherwise a caller-supplied met is stored with met_basis 'self_report', and with neither, met and met_basis are null. Prefer outcomeId: the outcome's text, index, and id are derived server-side from the intent row, so client input can never mislabel a measurement; the legacy outcomeIndex/outcomeText path remains for compatibility and still derives text/id when the index resolves. recorded_by is the authenticated user (the key's owner on the key path); source defaults to 'api' for key writes and 'manual' for session writes; evaluatedAt defaults to now when a measurement block omits it, since a measurement with no evaluation time cannot be placed against the change it measures. workspace_id derives from the intent row. No rate limiting on this endpoint.
Path parameters
id path parameter.
Request body
Response
Measurement recorded; returns the created measurement