PATCH /v1/projects/:projectId/ads/:platform/campaigns/:campaignId/budget
Update a campaign's daily or lifetime budget. Cents universally.
/v1/projects/:projectId/ads/{platform}/campaigns/:campaignId/budget- Auth
- Bearer
- Scope
- ads:write:budgets
Updates a campaign's budget. Cents universally — Layers translates per-platform at the proxy boundary. See LOCK 2.
Body
dailyBudgetCentsintegeroptionalNew daily budget in cents.lifetimeBudgetCentsintegeroptionalNew lifetime budget in cents.
Pass exactly one. Switching budget mode (daily ↔ lifetime) on Meta requires platform-side handling — Layers translates; some platforms refuse mid-flight switches and return PLATFORM_REJECTED.
Request
curl -X PATCH https://api.layers.com/v1/projects/$PROJECT_ID/ads/meta/campaigns/$CAMPAIGN_ID/budget \
-H "Authorization: Bearer $LAYERS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "dailyBudgetCents": 7500 }'Response
200 with {entityId, platform, dailyBudgetCents, lifetimeBudgetCents, verdictId, occurredAt}. The platform write is dispatched asynchronously — settlement (including the authority-gate verdict on draft/off axes) surfaces through the ads.write.executed / ads.write.denied webhooks. A success response means the write was durably dispatched, not yet applied platform-side.
Errors
| Code | When |
|---|---|
AUTHORITY_DENIED | tactical axis is off. |
VALIDATION | Both daily + lifetime set; budget below platform minimum. |
PLATFORM_REJECTED | Platform refused (mid-flight mode switch, or lifetime past endTime). |
INTERNAL | Dispatch failed — nothing was changed, on the platform or locally. Safe to retry. |
See also
POST /v1/projects/:projectId/ads/:platform/campaigns
Simplified create-campaign endpoint. Customer picks budget + outcome + management mode + creative mode; Layers handles the rest.
POST /v1/projects/:projectId/ads/:platform/campaigns/:campaignId/{pause,resume}
Pause or resume a campaign. Layers translates the verb to the platform's status enum.