Recommendations
The AI media buyer's suggestions, how to apply one safely, and why the apply is idempotent.
Scale a winner, pause an underperformer, reallocate budget, refresh a creative
before fatigue lands. GET /api/v1/recommendations lists the open ones for the
key's profile; the workspace-wide view is the MCP tool
list_workspace_recommendations.
All list parameters are comma-separated and validated strictly — an unknown
value is a 400, never a silent drop. A filter that silently drops an unknown
value returns a different set than the caller asked for and says nothing.
Applying one
POST /api/v1/recommendations/{id}/applyExecutes through the meta-actions layer: one write spine, one audit trail
(meta_action_log), one rollback system. There is no queue and nothing to
poll — the response says what happened.
`Idempotency-Key` is required
1–256 characters. Leg-level dedup is automatic (the executor derives its keys
from the recommendation id), so retrying an already-applied recommendation
answers 200 with replayed: true rather than double-spending a budget.
GET /api/v1/recommendations/{id}/diagnose answers why did this
recommendation do what it did — the read to make before explaining an applied
change to a client, and the one to make when it did not do what you expected.
POST /api/v1/recommendations/{id}/dismiss closes one without applying it.
When a human should approve first
require_approval: true on the apply mints an approve
hand-off carrying the exact preview, and answers
202 with {status: "awaiting_approval", handoff: {id, url, expires_at}}
having written nothing. The human opens the URL signed out, sees what
changes and on which account, and presses Approve or Reject; your agent polls
GET /api/v1/handoffs/{id} for the same result payload the direct call
returns.
Approval is OR'd, never AND'd
It is required when the principal is not a workspace owner/admin, or
whenever any caller passes require_approval: true. The second is the agency
case: an owner/admin token deliberately routing every Meta write on a client's
account past the client. Rejecting or expiring leaves no partial write, and the
pending action's own row is the audit record — status plus
result.outcome ∈ approved | rejected | expired | failed.
Over MCP, apply_recommendation's confirm mints the same object under the
same rule.
Until then, the MCP tool's preview → dry_run → confirm ceremony plus the
workspace-level mcp_writeback_enabled gate is the safety boundary — see
Write-back.
Forecast outlook
GET /api/v1/forecast-outlook is the portfolio-grain forecast for the next
7 days: projected impressions and attributed outcomes with 80% prediction
intervals from split-conformal calibration (calibrated coverage bands, not
Gaussian σ), projected average cost per outcome, counts of emerging and at-risk
top performers, per-tier fatigue histograms, and the budget at risk.
| Method | Path | What it does |
|---|---|---|
GET | /api/v1/forecast-outlook | Workspace portfolio forecast outlook (Phase 4) |
GET | /api/v1/recommendations | List open recommendations for this key's profile |
POST | /api/v1/recommendations/{id}/apply | Apply a recommendation (inline, terminal response) |
GET | /api/v1/recommendations/{id}/diagnose | Why did this recommendation do what it did |
POST | /api/v1/recommendations/{id}/dismiss | Dismiss a recommendation |
Generated from openapi.json. The full request and response schema for every operation is in the OpenAPI document.