{"openapi":"3.1.0","info":{"title":"Viral4All Ads API","version":"1.2.0","description":"Run your Meta ads from any AI or automation. Every MCP tool is POST /api/public/v1/tools/{name}. Changes that spend money return an approve_url: nothing changes until the owner approves it. The owner's limits are enforced on the server."},"servers":[{"url":"https://ads.viral4all.com"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key (sk_meta_…) from the API keys page, or an OAuth access token."}}},"security":[{"bearer":[]}],"paths":{"/api/public/v1/tools":{"get":{"operationId":"listTools","summary":"List the tools this key can use","responses":{"200":{"description":"Tools with their input schemas"},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_list_ads":{"post":{"operationId":"meta_list_ads","summary":"List Meta ads","description":"List every Meta ad on the connected account with status, budget, spend, impressions, reach, interactions and destination link, plus the owner's goals and the hard limits every change request must stay inside.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"datePreset":{"type":"string","enum":["today","last_7d","last_30d","last_90d","maximum"],"default":"last_30d"},"onlyRunning":{"type":"boolean","default":false},"limit":{"type":"integer","minimum":1,"maximum":500,"default":100},"offset":{"type":"integer","minimum":0,"default":0,"description":"Skip this many ads (paging)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_pause_ads":{"post":{"operationId":"meta_pause_ads","summary":"Pause Meta ads","description":"Pause one or many live Meta ads, ad sets or campaigns by id.","x-required-scope":"ads:status","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":50}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_resume_ads":{"post":{"operationId":"meta_resume_ads","summary":"Resume Meta ads (needs your approval)","description":"Ask to restart paused Meta ads, ad sets or campaigns by id. Nothing changes yet: returns a summary, an approve_url and a confirm_token. Give the user the summary and approve_url; the change runs only when they approve it there.","x-required-scope":"ads:status","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":50}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_set_budget":{"post":{"operationId":"meta_set_budget","summary":"Change a Meta budget (needs your approval)","description":"Ask to set the daily or lifetime budget of an ad set or campaign, in minor units (cents). Meta validates it, but nothing changes yet: returns a summary (from -> to, in currency), an approve_url and a confirm_token. Give the user the summary and approve_url; the change runs only when they approve it…","x-required-scope":"ads:budget","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"objectId":{"type":"string","minLength":1},"kind":{"type":"string","enum":["daily","lifetime"],"default":"daily"},"budgetMinorUnits":{"type":"integer","minimum":100,"maximum":100000000}},"required":["objectId","budgetMinorUnits"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_update_creative":{"post":{"operationId":"meta_update_creative","summary":"Update a Meta ad's link or creative (needs your approval)","description":"Ask to change an ad's destination (website URL or WhatsApp number), copy, call to action, image URL or video id. Nothing changes yet: returns a summary, an approve_url and a confirm_token. Give the user the summary and approve_url; the change runs only when they approve it there.","x-required-scope":"ads:creative","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"adId":{"type":"string","minLength":1},"destination":{"type":"string","enum":["website","whatsapp","facebook_page","messenger"]},"destinationValue":{"type":"string","minLength":1,"maxLength":500},"headline":{"type":"string","minLength":1,"maxLength":255},"primaryText":{"type":"string","minLength":1,"maxLength":2000},"callToAction":{"type":"string","minLength":2,"maxLength":40},"imageUrl":{"type":"string","format":"uri"},"videoId":{"type":"string","maxLength":64},"thumbnailHash":{"type":"string","maxLength":128}},"required":["adId"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_confirm_action":{"post":{"operationId":"meta_confirm_action","summary":"Check a pending Meta change","description":"Check what happened to a change prepared by meta_resume_ads, meta_set_budget, meta_update_creative, meta_update_adset or meta_archive: waiting_for_approval, done (with the result read back from Meta), undone, failed or rejected, plus any note the owner left. It never makes the change itself; only t…","x-required-scope":"ads:status or ads:budget or ads:creative or ads:edit","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_token":{"type":"string","minLength":10,"maxLength":200}},"required":["confirm_token"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_upload_media":{"post":{"operationId":"meta_upload_media","summary":"Upload media to Meta from a URL","description":"Download an image or video from a public https URL, store it, and register it with Meta so it can be used in an ad. Returns an image hash or video id.","x-required-scope":"media:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"filename":{"type":"string","maxLength":200}},"required":["url"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_create_ad":{"post":{"operationId":"meta_create_ad","summary":"Create a Meta campaign","description":"Create a full paused Meta campaign: campaign, ad set with budget and targeting, creative and ad. Resume it with meta_resume_ads when ready.","x-required-scope":"ads:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":200},"objective":{"type":"string","enum":["OUTCOME_TRAFFIC","OUTCOME_ENGAGEMENT","OUTCOME_AWARENESS"],"default":"OUTCOME_TRAFFIC"},"budgetKind":{"type":"string","enum":["daily","lifetime"],"default":"daily"},"budgetMinorUnits":{"type":"integer","minimum":100,"maximum":100000000},"countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2},"minItems":1,"maxItems":20,"default":["US"]},"destination":{"type":"string","enum":["website","whatsapp","facebook_page","messenger"],"default":"website"},"destinationValue":{"type":"string","minLength":1,"maxLength":500},"headline":{"type":"string","minLength":1,"maxLength":255},"primaryText":{"type":"string","minLength":1,"maxLength":2000},"callToAction":{"type":"string","minLength":2,"maxLength":40},"imageUrl":{"type":"string","format":"uri"},"videoId":{"type":"string","maxLength":64},"thumbnailHash":{"type":"string","maxLength":128}},"required":["name","budgetMinorUnits","destinationValue","headline","primaryText"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_sync_now":{"post":{"operationId":"meta_sync_now","summary":"Refresh Meta data","description":"Pull the latest spend, results and creative details from Meta and report what changed since the last sync.","x-required-scope":"sync:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_get_insights":{"post":{"operationId":"meta_get_insights","summary":"Meta ads report","description":"Performance report at account, campaign, ad set or ad level: spend, impressions, reach, frequency, clicks, CTR, CPC, CPM, results, cost per result, ROAS and every action count. Optional breakdowns (age, gender, country, placement, device), daily rows and id filters. Money is in minor units (cents).","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"level":{"type":"string","enum":["account","campaign","adset","ad"],"default":"campaign"},"datePreset":{"type":"string","enum":["today","yesterday","last_7d","last_14d","last_28d","last_30d","last_90d","this_month","last_month","maximum"],"default":"last_7d"},"since":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"With until, a custom range instead of datePreset."},"until":{"$ref":"#/properties/since"},"breakdowns":{"type":"array","items":{"type":"string","enum":["age","gender","country","region","publisher_platform","platform_position","device_platform","impression_device"]},"maxItems":2},"daily":{"type":"boolean","default":false,"description":"One row per day."},"campaignIds":{"type":"array","items":{"type":"string","pattern":"^\\d+$"},"minItems":1,"maxItems":50},"adsetIds":{"$ref":"#/properties/campaignIds"},"adIds":{"$ref":"#/properties/campaignIds"},"accountId":{"type":"string","pattern":"^\\d+$","description":"Ad account id without act_. Defaults to the active account."},"limit":{"type":"integer","minimum":1,"maximum":500,"default":100}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_list_campaigns":{"post":{"operationId":"meta_list_campaigns","summary":"List Meta campaigns, ad sets and ads","description":"The full structure: campaigns with their ad sets (budget, schedule, optimization goal) and ads (headline, link), each with spend, clicks, results and cost per result. Budgets and money are in minor units (cents).","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"datePreset":{"type":"string","enum":["today","last_7d","last_30d","last_90d","maximum"],"default":"last_7d"},"onlyRunning":{"type":"boolean","default":false},"accountId":{"type":"string","pattern":"^\\d+$","description":"Ad account id without act_. Defaults to the active account."},"limit":{"type":"integer","minimum":1,"maximum":200,"default":25,"description":"Campaigns per page."},"offset":{"type":"integer","minimum":0,"default":0,"description":"Skip this many campaigns (paging)."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_list_accounts":{"post":{"operationId":"meta_list_accounts","summary":"List connected ad accounts","description":"Every connected Meta ad account with currency, time zone and whether it can deliver, and which one the tools act on.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_switch_account":{"post":{"operationId":"meta_switch_account","summary":"Switch the active ad account","description":"Make another connected ad account the one every tool and the dashboard act on. Spends nothing.","x-required-scope":"sync:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","pattern":"^\\d+$"}},"required":["accountId"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_search_targeting":{"post":{"operationId":"meta_search_targeting","summary":"Search Meta targeting","description":"Find interests (with audience size) or locations (countries, regions, cities) to target. Use the results with meta_update_adset or meta_create_ad.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["interest","location"]},"query":{"type":"string","minLength":2,"maxLength":100},"limit":{"type":"integer","minimum":1,"maximum":25,"default":10}},"required":["type","query"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_list_audiences":{"post":{"operationId":"meta_list_audiences","summary":"List custom audiences","description":"Custom and lookalike audiences on the ad account with type, approximate size and whether they're ready to use.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","pattern":"^\\d+$","description":"Ad account id without act_. Defaults to the active account."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_activity_log":{"post":{"operationId":"meta_activity_log","summary":"What changed recently","description":"Recent change requests (waiting, approved, rejected, failed, undone, with the owner's notes) and the ad changes the sync detected, newest first.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":100,"default":30}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_connection_status":{"post":{"operationId":"meta_connection_status","summary":"Meta connection status","description":"Whether Meta is connected, the active ad account, when the login expires and the last sync. Includes the link where the user connects or reconnects Meta, sets limits and approves changes.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_duplicate":{"post":{"operationId":"meta_duplicate","summary":"Duplicate a campaign, ad set or ad","description":"Make a PAUSED copy (campaigns and ad sets copy what's inside them). Spends nothing until it's resumed, which needs the owner's approval. Counts toward the owner's AI changes per day.","x-required-scope":"ads:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","pattern":"^\\d+$"},"level":{"type":"string","enum":["campaign","adset","ad"]}},"required":["id","level"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_update_adset":{"post":{"operationId":"meta_update_adset","summary":"Edit an ad set's targeting, schedule or bid (needs your approval)","description":"Ask to change an ad set: countries (replace the location targeting), ages, genders, interests (from meta_search_targeting; replaces detailed targeting, [] clears it), name, end time (ISO 8601) or bid cap in minor units. Meta validates it, but nothing changes yet: returns a field-by-field summary, a…","x-required-scope":"ads:edit","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"adsetId":{"type":"string","pattern":"^\\d+$"},"countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2},"minItems":1,"maxItems":25},"ageMin":{"type":"integer","minimum":13,"maximum":65},"ageMax":{"type":"integer","minimum":13,"maximum":65},"genders":{"type":"string","enum":["all","male","female"]},"interests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["id","name"],"additionalProperties":false},"maxItems":25},"name":{"type":"string","minLength":1,"maxLength":200},"endTime":{"type":"string","format":"date-time"},"bidAmountMinorUnits":{"type":"integer","minimum":1,"maximum":100000000}},"required":["adsetId"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/meta_archive":{"post":{"operationId":"meta_archive","summary":"Archive campaigns, ad sets or ads (needs your approval)","description":"Ask to archive by id: they stop for good and leave the active lists. Nothing changes yet: returns a summary, an approve_url and a confirm_token. It can't be undone, so suggest meta_pause_ads when the user may want them back.","x-required-scope":"ads:status","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","pattern":"^\\d+$"},"minItems":1,"maxItems":50}},"required":["ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/list_campaigns":{"post":{"operationId":"list_campaigns","summary":"List workspace campaign notes","description":"List campaign plans saved in the Viral4All Ads workspace (local notes, not live Meta campaigns; use meta_list_campaigns for those), optionally filtered by status or platform.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["draft","active","paused","completed"]},"platform":{"type":"string","description":"Platform id, e.g. meta, google_ads, x, linkedin"},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/create_campaign":{"post":{"operationId":"create_campaign","summary":"Save a workspace campaign note","description":"Save a campaign plan in the Viral4All Ads workspace. This is a local note: nothing is created on Meta (use meta_create_ad for that).","x-required-scope":"ads:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"platform":{"type":"string","enum":["meta","google_ads","x","linkedin","tiktok"],"description":"Ad platform the campaign runs on."},"objective":{"type":"string","enum":["awareness","traffic","engagement","leads","sales"],"default":"awareness"},"budget_usd":{"type":"number","minimum":0,"default":0}},"required":["name","platform"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/update_campaign_status":{"post":{"operationId":"update_campaign_status","summary":"Update a workspace campaign note","description":"Change the status label of a campaign plan in the Viral4All Ads workspace. Local notes only: live Meta ads are not affected.","x-required-scope":"ads:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"campaign_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["draft","active","paused","completed"]}},"required":["campaign_id","status"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/list_posts":{"post":{"operationId":"list_posts","summary":"List workspace post drafts","description":"List social post drafts saved in the Viral4All Ads workspace (local notes, nothing is published), optionally filtered by status or platform.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["draft","scheduled","published"]},"platform":{"type":"string"},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/create_post":{"post":{"operationId":"create_post","summary":"Save a workspace post draft","description":"Save a social post draft in the Viral4All Ads workspace. Local notes only: nothing is posted anywhere.","x-required-scope":"ads:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","minLength":1,"maxLength":5000},"platform":{"type":"string","enum":["x","linkedin","tiktok","slack"]},"scheduled_at":{"type":"string","format":"date-time","description":"ISO 8601 time to publish. Omit to save as a draft."}},"required":["content","platform"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/public/v1/tools/performance_summary":{"post":{"operationId":"performance_summary","summary":"Workspace notes summary","description":"Totals across the campaign plans saved in the Viral4All Ads workspace. For live Meta numbers use meta_get_insights.","x-required-scope":"ads:read","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","description":"Limit the summary to one platform id."}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's result","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}}}}