Layers
ApiReferenceRecommendations

PATCH /v1/projects/:projectId/recommendations/:recommendationId

Acknowledge, dismiss, or mark a recommendation as acted-on. Idempotent.

View as Markdown
PATCH/v1/projects/{projectId}/recommendations/{recommendationId}
Phase 1stable
Auth
Bearer
Scope
metrics:read

Flip a recommendation's status. Use this to clear a row out of your default status=open view (dismissed), record that an agent has handled it (acted_on), or just mark it as seen (acknowledged).

The endpoint is idempotent — re-PATCHing to the same status returns the same row without an additional state change. Status transition timestamps (acknowledged_at, dismissed_at, acted_on_at) are stamped on the first transition into each terminal state and preserved across later changes.

Path
  • projectId
    string (UUID)required
    Project the recommendation belongs to.
  • recommendationId
    stringrequired
    Wire id from the list endpoint (`rec_<uuid>`).
Body
  • status
    stringrequired
    Target status.
    One of: open, acknowledged, dismissed, acted_on
  • note
    stringoptional
    Optional free-text reason (≤1024 chars). Persisted alongside the row for audit.

Example request

curl -X PATCH \
  "https://api.layers.com/v1/projects/prj_254a4ce1.../recommendations/rec_5e4d3c2b..." \
  -H "Authorization: Bearer lp_..." \
  -H "Content-Type: application/json" \
  -d '{"status":"dismissed","note":"Covered by manual creative refresh"}'

Response

200OK
{
  "recommendationId": "rec_5e4d3c2b...",
  "status": "dismissed",
  "updatedAt": "2026-04-26T22:30:00Z"
}

Notes

  • The optimizer pipeline that generates recommendations refreshes confidence, rationale, and evidence on subsequent runs but never overwrites a partner-flipped status. Once you mark something dismissed, it stays dismissed even if the underlying signal persists.
  • A dismissed recommendation is hidden from the default status=open filter on the list endpoint. Pass status=dismissed to retrieve it.
  • Re-opening a dismissed row (status=open) clears dismissed_at semantically (the row goes back to the default view) but keeps the audit trail in note and the previous timestamp columns.

See also

On this page