Layers
Partner APIAPI referenceAds

POST /v1/projects/:projectId/ads/:platform/pending/:pendingId/{approve,reject}

Approve or reject a pending optimizer action queued by the gate's `draft` axes.

View as Markdown
POST/v1/projects/:projectId/ads/{platform}/pending/:pendingId/approve
Phase 1stable
Auth
Bearer
Scope
ads:write:pending
POST/v1/projects/:projectId/ads/{platform}/pending/:pendingId/reject
Phase 1stable
Auth
Bearer
Scope
ads:write:pending

Approve or reject a pending optimizer action. Approved actions dispatch on the optimizer's next 6h tick (or earlier if you trigger a fresh optimizer run). Rejected actions are flagged and never dispatch.

Approve body

Body (optional)
  • comment
    stringoptional
    Free-form note attached to the approval audit row.

Reject body

Body
  • reason
    stringrequired
    Why the action was rejected. Surfaces in the audit log + on customer-side optimizer dashboard.

Approve request

curl -X POST https://api.layers.com/v1/projects/$PROJECT_ID/ads/meta/pending/$PENDING_ID/approve \
  -H "Authorization: Bearer $LAYERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "comment": "Looks good — spend pacing is on target." }'

Response

{
  "pendingId": "pa_01HZX9...",
  "status": "approved",
  "dispatched": false,
  "dispatchedAt": null,
  "verdictId": "ver_01HZX9..."
}

dispatched: false is the immediate state — the optimizer's next tick (within 6 hours) executes the approved action. The approval.dispatched webhook fires when the platform-side mutation lands; dispatchedAt populates on the next read.

Errors

CodeWhen
NOT_FOUNDPending action doesn't exist or is already terminal.
FORBIDDEN_SCOPEKey lacks ads:write:pending.
CONFLICTPending action is already approved/rejected/dispatched.

See also

On this page