Improved

Browser admins can promote learnings to data_product scope at create time

The POST /api/v1/accounts/{accountId}/data-products/{dataProductId}/learnings endpoint now accepts the scope field from browser callers when the authenticated user is an admin of the data product's account. Previously the field was silently dropped for every browser caller and only honored for M2M agents. This unblocks the in-chat propose-learning card and the feedback-modal "Share instructions for the AI agent" panel from creating learnings that apply to every user of a data product — without requiring a separate promotion step from the admin console.

Modified Endpoint

  • POST /api/v1/accounts/{accountId}/data-products/{dataProductId}/learnings

What's New

  • Browser admin callers can now pass "scope": "data_product" and the field is honored.
  • When honored, the API also persists promotedBy (the admin's DB user UUID) and promotedAt (server-side timestamp). These distinguish human admin promotions from system-generated shared learnings in the admin console.
  • Browser non-admin callers that pass "scope": "data_product" are silently downgraded to the column default "user" with a server-side warn log; the response shape is unchanged.
  • If params.accountId does not match the workspace's actual accountId (tampered client), the API force-downgrades to "user" with a warn log. The endpoint returns 404 dataProductNotFound if the workspace does not exist.
  • M2M behavior is unchanged: M2M callers continue to set scope freely without any admin gating.

Request Format

{
  "learningText": "Always use the booked-revenue column for pipeline reports",
  "category": "business_logic",
  "scope": "data_product"
}

Response Format

Same as before; the response surface now reflects the persisted scope, promotedBy, and promotedAt fields on the returned learning.

Migration Notes

No client changes are required for callers that were already ignoring scope. Clients that want to surface the new admin-gated promotion path should:

  1. Determine whether the user is an admin of the workspace's account (use GET /api/v1/accounts/{accountId}/me or your existing role check).
  2. Show a scope selector with "user" and "data_product" options to admins only.
  3. Send the selected value as "scope" in the POST body.

Non-admin clients should continue omitting the field; the server forces "user" for them either way.