Ads
Ads go through an ads connection: one more account of the profile, with platform meta-ads, google-ads, linkedin-ads, tiktok-ads, pinterest-ads, x-ads or reddit-ads. It does not publish: it reaches one or more of the network’s ad accounts, which are the ones that pay.
Connect
Section titled “Connect”GET /v1/connect/meta-ads (or the platform you need) and send the user to the URL, like any connection:
- Meta uses Meta’s business login: it creates no Facebook account for posting. Whoever connects must be an admin of the business portfolio.
- LinkedIn, TikTok, Pinterest and Google: when the profile’s social account already granted ads access, it comes straight back without asking anything.
- X Ads hangs from the profile’s X account: connect it first.
Then list its ad accounts. Their id is the adAccountId of every other call.
curl "https://api.marsial.dev/v1/accounts/acc_ads123/ads/ad-accounts" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/accounts/acc_ads123/ads/ad-accounts', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/accounts/acc_ads123/ads/ad-accounts", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Results and control
Section titled “Results and control”curl "https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns?from=2026-10-01&to=2026-10-31" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns?from=2026-10-01&to=2026-10-31', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns?from=2026-10-01&to=2026-10-31", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Returns the campaigns (including the ones created in the network’s ads manager) with spend, impressions, clicks, reach and conversions for the period. To pause, resume or change the budget:
curl -X PATCH "https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns/120210000000" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": "paused", "budget": { "amount": 25, "type": "daily" } }'const res = await fetch('https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns/120210000000', { method: 'PATCH', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "status": "paused", "budget": { "amount": 25, "type": "daily" } }),});const { data } = await res.json();import os, requests
res = requests.patch( "https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns/120210000000", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "status": "paused", "budget": { "amount": 25, "type": "daily" } },)data = res.json()["data"]Boost a post
Section titled “Boost a post”Turns the published copy of a Marsial post into an ad. accountId is the account of that copy (for example, the Instagram) and adAccountId, the ad account that pays.
curl -X POST "https://api.marsial.dev/v1/posts/pst_9f2a/boost" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "accountId": "acc_3k9x2m", "adAccountId": "act_120210", "name": "Autumn", "goal": "traffic", "budget": { "amount": 40, "type": "daily" }, "targeting": { "countries": [ "GB", "IE" ], "ageMin": 25, "ageMax": 45 } }'const res = await fetch('https://api.marsial.dev/v1/posts/pst_9f2a/boost', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "accountId": "acc_3k9x2m", "adAccountId": "act_120210", "name": "Autumn", "goal": "traffic", "budget": { "amount": 40, "type": "daily" }, "targeting": { "countries": [ "GB", "IE" ], "ageMin": 25, "ageMax": 45 } }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/posts/pst_9f2a/boost", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "accountId": "acc_3k9x2m", "adAccountId": "act_120210", "name": "Autumn", "goal": "traffic", "budget": { "amount": 40, "type": "daily" }, "targeting": { "countries": [ "GB", "IE" ], "ageMin": 25, "ageMax": 45 } },)data = res.json()["data"]goal is what the network optimises for (engagement, traffic, awareness, video_views…; each network takes a subset). A lifetime budget needs endDate. The network reviews the ad before showing it.
Create campaigns
Section titled “Create campaigns”POST /v1/accounts/{id}/ads/campaigns creates campaign, ad group and ad in one call, in each network’s terms: adAccountId, goal, budgetAmount, budgetType, the creative (headline, body, imageUrl or videoUrl, linkUrl, callToAction) and targeting. Marsial fills the connection in; do not send accountId.
curl -X POST "https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "adAccountId": "act_120210", "name": "Sale", "goal": "traffic", "budgetAmount": 30, "budgetType": "daily", "headline": "Winter sale", "body": "Up to 40% off coats", "imageUrl": "https://cdn.acme.com/sale.jpg", "linkUrl": "https://acme.com/sale", "callToAction": "SHOP_NOW", "targeting": { "countries": [ "GB" ] } }'const res = await fetch('https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "adAccountId": "act_120210", "name": "Sale", "goal": "traffic", "budgetAmount": 30, "budgetType": "daily", "headline": "Winter sale", "body": "Up to 40% off coats", "imageUrl": "https://cdn.acme.com/sale.jpg", "linkUrl": "https://acme.com/sale", "callToAction": "SHOP_NOW", "targeting": { "countries": [ "GB" ] } }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/accounts/acc_ads123/ads/campaigns", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "adAccountId": "act_120210", "name": "Sale", "goal": "traffic", "budgetAmount": 30, "budgetType": "daily", "headline": "Winter sale", "body": "Up to 40% off coats", "imageUrl": "https://cdn.acme.com/sale.jpg", "linkUrl": "https://acme.com/sale", "callToAction": "SHOP_NOW", "targeting": { "countries": [ "GB" ] } },)data = res.json()["data"]Conversions
Section titled “Conversions”Send sales and leads back to the network so it optimises better: Meta’s Conversions API, Google offline conversions, LinkedIn and TikTok.
curl -X POST "https://api.marsial.dev/v1/accounts/acc_ads123/ads/conversions" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "pixelId": "1234567890", "events": [ { "eventName": "Purchase", "eventTime": 1793000000, "user": { "email": "ana@acme.com" }, "value": 59.9, "currency": "GBP" } ] }'const res = await fetch('https://api.marsial.dev/v1/accounts/acc_ads123/ads/conversions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "pixelId": "1234567890", "events": [ { "eventName": "Purchase", "eventTime": 1793000000, "user": { "email": "ana@acme.com" }, "value": 59.9, "currency": "GBP" } ] }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/accounts/acc_ads123/ads/conversions", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "pixelId": "1234567890", "events": [ { "eventName": "Purchase", "eventTime": 1793000000, "user": { "email": "ana@acme.com" }, "value": 59.9, "currency": "GBP" } ] },)data = res.json()["data"]Approving changes
Section titled “Approving changes”Turn on ads approval (PATCH /v1/workspace with requireAdsApproval: true, or in the dashboard, Settings → Team) and what spends money (resuming, budget changes, boosts and new campaigns) does not reach the network when members or AI agents ask for it: the API answers 202 with the request (adr_…, status: "pending") and an owner or admin approves or rejects it. Pausing always applies at once, since it only stops spending. API keys used on /v1 are your integration and never wait; an agent coming through the MCP server always waits, even when it acts for an owner.
curl "https://api.marsial.dev/v1/ads/requests?status=pending" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/ads/requests?status=pending', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/ads/requests?status=pending", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]curl -X POST "https://api.marsial.dev/v1/ads/requests/adr_3m8p2q/review" \ -H "Authorization: Bearer $MARSIAL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "decision": "approve" }'const res = await fetch('https://api.marsial.dev/v1/ads/requests/adr_3m8p2q/review', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "decision": "approve" }),});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/ads/requests/adr_3m8p2q/review", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"}, json={ "decision": "approve" },)data = res.json()["data"]Approving sends the change to the network right then and the request becomes approved; if the network refuses it, it ends failed with the reason in error. With reject you can leave a note for whoever asked. AI agents can never approve.
What it costs
Section titled “What it costs”You pay ad spend directly to each network, on its ad account. Marsial charges the connection as one more account and, beyond 500 active ads, each managed ad (rates).
In the dashboard, the Ads section shows the campaigns and lets you pause them and change their budget; a published post’s detail has the button to boost it. AI agents can do the same through the MCP server.
© 2026 Marsial by TWOFACES ·marsial.dev ·Dashboard ·soporte@twofacesco.com